我有一个 Flink 1.11 作业,它使用来自 Kafka 主题的消息、对它们进行键控、过滤它们(keyBy 后跟自定义 ProcessFunction),并通过 JDBC 接收器将它们保存到数据库中(如下所述:https://ci.apache.org/projects/flink/flink-docs-release-1.11/dev/connectors/jdbc.html )
Kafka 消费者使用以下选项进行初始化:
properties.setProperty("auto.offset.reset", "earliest")
kafkaConsumer = new FlinkKafkaConsumer(topic, deserializer, properties)
kafkaConsumer.setStartFromGroupOffsets()
kafkaConsumer.setCommitOffsetsOnCheckpoints(true)
在集群上启用了检查点。
我想要实现的是保证将所有过滤后的数据保存到数据库中,即使数据库关闭了,比如说 6 小时,或者在保存到数据库时出现编程错误并且作业需要更新、重新部署和重新启动。
要发生这种情况,Kafka 偏移量的任何检查点都应该意味着
在查看 JdbcSink 的实现时,我发现它并没有真正保持任何将被检查点/恢复的内部状态 - 相反,它的检查点是对数据库的写出。现在,如果此写入在检查点期间失败,并且 Kafka 偏移量确实被保存,我将处于“丢失”数据的情况 - 来自 Kafka 的后续读取将从已提交的偏移量恢复,并且当 db写入失败现在不再从 Kafka 读取,也不在数据库中。
那么有没有办法在完整的管道(Kafka -> Flink -> DB)无法执行时停止推进 Kafka 偏移量 - 或者这里的解决方案(在 1.13 之前的世界中)是创建我自己的GenericJdbcSinkFunction 会保持一些 ValueState 直到数据库写入成功?
答案 0 :(得分:0)
我可以看到 3 个选项:
TwoPhaseCommitSinkFunction
或使用 SinkFunction
和 CheckpointedFunction
实现您自己的 CheckpointListener
。基本上,您在成功检查点后创建一个新事务并使用 notifyCheckpointCompleted
提交它。