flink 容错机制
字数: 0 字 时长: 0 分钟
检查点
在流处理中,我们可用用存档读档的思路,将某个时间点所有的状态保存下来,这份存档就是 检查点。
检查点的保存
在 Flink 中检查点的保存是周期性触发的,间隔时间可以进行设置。我们应该在所有任务(算子)都恰好处理完一个相同的输入数据的时候,将它们的状态保存下来。如果出现故障,我们只需要让源 (source) 任务向数据源重新提交偏移量、请求重放数据就可以了。这需要源任务把偏移量作为算子状态保存下来,而且外部数据源能够重置偏移量,比如 kafka
检查点算法
Flink 采用基于 Chandy-Lamport 算法的分布式快照,可以在不暂停整体流的前提下,将状态备份到检查点。
检查点分界线 Barrier
借鉴水位线的设计,在数据流中插入一个特殊的数据结构,专门用来表示触发检查点保存的时间点。收到保存检查点的指令后, Source 任务可以在当前数据流中插入这个结构; 之后的所有任务只要遇到它就开始对状态做持久化快照保存。
Barrier 对齐的精准一次
多并行度的情况下,比如 Map
下游两个子任务,那么就会产生多个 Barrier
,此时需要将多个 Barrier
对齐,才能保证精确一次。如图所示, sum2
收到了 map1
和 map2
的 Barrier
,然后保存状态;而 sum1
只收到 map2
的 Barrier
,即使此时 sum1
收到了 map2
发送的 Barrier
之后的数据也不会处理,直到收到 map1
的 Barrier
之后保存状态之后才会继续处理数据。
Barrier 对齐的至少一次
Barrier
对齐的精准一次需要等待分界线对齐,这个过程可能会导致数据堆积,因此有另一种策略,就是在分界线对齐的过程中,允许继续处理 Barrier
之后的数据; 那么如果故障重启之后,会导致这部分 Barrier
之后的数据重复计算处理。
Barrier 非对齐的精准一次
Barrier
对齐的精准一次可能造成数据堆积,造成或加剧反压。因此,Flink 1.11 提供了非对齐的精确一次算法,如下图所示:当蓝色的 Barrier
到 sum1
的输入缓冲区时,就之间越过,到达 sum1
的输出缓冲区末端,并标记越过的数据和其他 Barrier
之后的数据,将这些标记的数据也一并存储在检查点中。