一致性检查点
Flink容错机制的核心就是一致性检查点。
有状态流应用的一致检查点,其实就是所有任务的状态,在某个时间点的一份拷贝(一份快照);这个时间点,应该是所有任务都恰好处理完一个相同的输入数据的时候。
这是一个奇偶数分别求和的应用,偶数求和已经计算了2+4
,奇数求和计算了1+3+5
,source保存的偏移量为5。
假设在奇数求和只计算了1+3
,5还在路上的时候保存了快照到Storage中,系统故障后进行了快照重放,那么source中是要重放为5呢,还是继续读下一条数据呢?
如果预先设计,重放的时候指定让source重放为5,那么假设偶数求和中的4也还在路上呢?
根本无法预知source应该被重放为多少,所以必须在所有任务都恰好处理完一个相同的输入数据的时候保存快照。在奇数求和处理完5后,状态才应该保存在Storage中。
如何从检查点恢复状态
继续这个应用,在7进入奇数列的时候出意外了,sum_odd挂掉了,那么就要从检查点恢复状态了。
第一步:重启应用
第二步:重置状态
从检查点重新启动应用程序后,其内部状态与检查点完成时的状态完全相同。
第三步:恢复状态
开始消费并处理检查点到发生故障之间的所有数据。
检查点算法
经过上面的介绍,检查点算法有个简单的印象在脑子里面,和虚拟机差不多:暂停应用,保存快照,需要的时候恢复快照。
但是Flink的检查点算法是基于 Chandy-Lamport 算法的分布式快照算法,他可以将检查点的保存和数据处理分离开,不暂停整个应用,比如要拍全班的照片,可以让有空的同学来拍个人照,然后一个一个p到全班照上面。
Flink的检查点算法提出了一种特殊的数据形式叫检查点分界线(Checkpoint Barrier) ,他用来把一条流上数据按照不同的检查点分开。
老师怕没有处理完的全班照丢失,让几个人提醒自己保存备份。比如P了N个同学的个人照后,就有一个人(检查点分界线)来告诉老师记得保存备份(快照)。
分界线之前到来的数据导致的状态更改,都会被包含在当前分界线所属的检查点中;而基于分界线之后的数据导致的所有更改,就会被包含在之后的检查点中。
这是一个两个输入流的应用程序,用并行的两个 Source 任务来读取,两个sum算子进行累加计算后将状态输出到slink。
JobManager每隔一段时间会向每个 source 任务发送一条带有新检查点 ID 的消息,通过这种方式来启动检查点。
数据源将它们的状态写入检查点,并发出一个检查点 barrier。
状态后端在状态存入检查点之后,会返回通知给 source 任务,source 任务就会向 JobManager 确认检查点完成
当收到所有输入分区的 barrier 时,任务就将其状态保存到状态后端的检查点中,然后将 barrier 继续向下游转发
向下游转发检查点 barrier 后,任务继续正常的数据处理
Sink 任务向 JobManager 确认状态保存到 checkpoint 完毕,当所有任务都确认已成功将状态保存到检查点时,检查点就真正完成了
保存点
-
Flink 还提供了可以自定义的镜像保存功能,就是保存点(savepoints)
-
原则上,创建保存点使用的算法与检查点完全相同,因此保存点可以认为就是具有一些额外元数据的检查点
-
Flink不会自动创建保存点,因此用户(或者外部调度程序)必须明确地触发创建操作
-
保存点是一个强大的功能。除了故障恢复外,保存点可以用于:有计划的手动备份,更新应用程序,版本迁移,暂停和重启应用,等等