FlinkKafkaProducer 数据一致性

什么是数据的一致性

这所说的数据一致性指,在一个 Flink 任务遇到不可坑因素整体死掉或者部分死掉,已经外部存储介质死掉后,将死掉的部分重写启动后,计算结果和出现故障之前一致,不会产生任何的影响。

如果要实现这种效果,无论发生什么,所有算子做到如下要求:

  1. source 算子中,一条记录只向下游发送一次。
  2. 在聚合算子、合集算子、转换算子中一条数据只处理一次。
  3. 在 sink 算子中,一条数据只向外部存储介质中写入一次。

只要做到这些,我们就可以说,我们整个任务的数据是一致的。

今天就把 Flink 自己封装的 Kafka 的生产这和消费者拿出来看看,source 和 sink 是如何做数据一致性的。

刻舟求剑

大家都知道刻舟求剑的寓言故事。这个故事告诉做记号得重要性。同理,当我们每处理一条记录,我们就记录下来。
在这里插入图片描述

例如,类似如下格式的日志。

20216161032分 primary_key1 of a record

每当算子处理完一条消息,就记录下如上所示的日志。加入这个算子的实例失败了,当我们重新启动的时候吧,我们可以查找此日志,查到这个日志,我们就可以找到我们在失败之前处理到哪里了,然后从哪里开发处理数据。

这是一个非常简单的情况。我们知道 Flink 是一个分布式系统,任务上的多个算子会被安排到不同的服务器上跑。一个分布式系统要想做“记号”那可不是简单。我们就来看看 Flink 是如何做的。下面的图片展示了 Flink 做“记号”的过程。这个过程就叫“二次提交”。

在这里插入图片描述

二次提交的流程:

  1. JM 发送 checkpoint trigger

  2. 执行 snapshotState 方法,这里会执行 producer 的 flush 方法。这个方法会将 producer 缓存里面的数据发送完。

  3. TM 将 barrier 的快照保存到 backend 里面,包括 kafka transaction id 和 checkpoint id 的对应关系。

  4. 发送 checkpoint ACK 给 JM。

  5. 当所有的算子实例执行完对应的 checkpoint 以后 JM 调用算子的 notifyCheckpointComplete() 方法,进行后续对状态的处理。如果有一个 TM 没有发送对应的 ACK ,那么,这次 checkpoint 都不能算执行完成,如果超过了时间,JM 会调用各个算子的 notifyCheckpointAborted 方法,取消这次 chekcpoint。

Flink 在类 TwoPhaseCommitFunction 中实现了二次提交的逻辑, TwoPhaseCommitFunction 是一个抽象类,所以只说它还是不给你完全的解释 FlinkKafkaProducer 的数据一致性。

第一阶段-准备阶段:

当一个 barrier 过来后,一个 producer 实例调用 snapshotSate() ,将transactionId、checkpointId 保存在本地的 pendingCommitTransaction 里面,并且开启 kafka 的一个事务,最后将 transactionID 放到 backend。这一步的目的是将单个算子里面记录一下,写到那个 transacton id 了,

第二阶段-提交:

当所有的 producer 实例都完成了在同一个 barrier 里面的 snaptshot ,JobMannager 会收到各个 producer 实例的 ack ,然后JobMannager 回调 producer.notifyCompleteCheckpoint() , 这个函数的处理逻辑是将 pendingCommitTransactiond 中等待提交的事务ID删除掉,并将在本次 barrier 中的 transactionId 提交给 Kafka Coordinator。这样就完成了一次 checkpoint 和 kafka 一次事务。这就保证了当一个完整的 checkpoint 执行结束后,Flink kafka Producer 才会提交 tranaction id ,如果发生什么异常(例如宕机),checkpoint 无法完成,可能会重新启动任务,只要 transaction 没有提交,即使我们使用同一个 transaction 提交了重复的数据,也不会造成 kafka 里面数据重复,因为 Kafka coodinator 会悄悄的为我们去重的。

优点:模型简单,容易实现。

缺点:严重依赖 JobManager ,存在单节点故障隐患。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值