FlinkKafkaProdecer继承TwoPhaseCommitSinkFunction(分两个阶段提交sink),TwoPhaseCommitSinkFunction实现了连接的接口
CheclpointedFunction和CheckpointListener
实现CheckpointedFunction接口要实现initializeState和snapshosState方法
实现CheckpointListener接口要实现notifyCheckpointComplete和notifyCheckpointAborted方法
1.程序启动,在TwoPhaseCommitSinkFunction的initializeState方法中初始化一个listState(为了缓存写入的数据)
2.当有数据进入sink中,会调用invoked的方法,在该方法中,数据将使用kafkaProducer的连接将数据send(数据没有立即写入Kafka的broker,而是缓存到客户端),然后再有数据进入到sink中,再调用invoke方法,将数据使用的Kafka的producer发送,只要没有flush或者数据达到一定大小,数据就会缓存在客户端
3.随着时间的推移,在checkpoint中,会调用snapshosState方法,在该方法中,调用TwoPhaseCommitSinkFunction的snapshosState,在该方法中带哦用preCommit,在preCommit将Kafkaproducer的数据flush到broker中,但是没有提交事务(写入Kafka broker的数据是uncommitted状态),然后将缓存在客户端的数据持久化到stateBacked中
4.如果所有的subtask都完成了snapshosState,就会向jobmanager进行ACK应答,当job Manger收到该job这次checkpoint的ack以后,标记这次checkpoint成功,并且会向实现了checkpoint Listener接口的subtask发送checkpoint成功的消息,在subtask中会调用notifyCheckpointComplete方法,在该方法中提交事务,这样写入到Kafka中的数据才算真正成功.
5.如果checkpoint失败,所以subtask重启,然后从上一次的状态恢复数据,会接着以前的偏移量继续读,继续处理
6.如果checkpoint成功了,但是提交事务失败了,所有的subtask重启,然后在initializeState方法中恢复状态装的数据,再将数据写入到Kafka的broker中,并提交事务
分两个阶段提交,
preCommit,即在checkpoint时,将客户端缓存的数据flush到broker中(没有提交事务)
commit在整个这次checkpoint成功后,job manager通知实现checkpoint Listener接口的subtask(sink),提交事务