算子状态State的冥等性理解

334 阅读2分钟

背景:进公司之前,同事已经搭建了一套flink从source到sink的完整代码,然后我就一直在上面做各种迭代。

工作期间一直看各种技术文档,特别是对于flink的端到端的一次性保证始终不是很明白,最最坑的是,前同事搭建的代码是完全基于flink无状态算子规则,但是最后的计算结果用mongdb的原子语义统计分布式计算结果,完全没有用到状态计算,而我呢又是基于老代码来理解flink的执行流程,所以理解一直和网上说的大相径庭。

如下代码是mdb的计算:

这样做有个好处就是,完全不用关心什么state,checkpoint等等...因为我们是基于mdb做的计算,而flink干的事就是消费kafka数据,处理转换一下,window小合并一下,得到当前窗口的值,最后还得mdb.inc来做计算.


进入正题:

冥等性理解:flink消费100条相同的数据,得到的结果是100个相同的结果。

分析上面的理解其实就是一句话:sink到库里的数据,只能upset(覆盖更新),不能利用各种数据库来做计算

非冥等性:flink消费100条相同的数据,由于经过了state的计算,如累加,得到的结果是100个不断递增的结果。

那么这样就可以解决困扰我很久的一个问题,

job异常重启,获取最近一次的checkpoint,由于chk里面存储的offset偏移量和上一次成功时的各个算子下的状态数据(这里有个同学给我说还会存储当时正在被处理的源数据???),那么就会回退到MQ当时的偏移量重新消费,各个算子下的状态也被赋上当时chk成功时的状态值,再来消费一圈,使用state来做计算,得到正确的结果,因为不会再利用数据库的计算来得结果,这里只需要不断更新数据库里的结果值就可以了,那么结果就准确无误了