大数据理论篇 No.5-聊聊Flink中的Checkpoint和Savepoint

第1章 Checkpoint

Flink作为分布式流计算处理引擎,而分布式处理引擎必须面对的问题就是故障,例如:进程被强制关闭、服务器宕机、网络连接中断等等。

Flink为了解决故障问题,保证在发生故障时能够完好的恢复,并且不丢失状态数据,定义了checkpoint机制。

在checkpoint机制中不得不提的一个东西就是:checkpoint barrier。他是一个特殊标记分隔符。barrier不通过数据源算子注入到数据流当中。为了标记所属的checkpoint范围,每个barrier会带有一个checkpoint编号,相当于在逻辑上把数据流切分成了多个块。在barrier之前的数据所产生的state会被包含在barrier所对应的checkpoint当中。barrier之后的数据则对用的是下个barrier和下一次checkpoint。并且Flink可以同时有多个checkpoint持续产生(比如checkpoint N、checkpoint N+1等等)。

我们透过下面这几张图,来看一下Flink checkpoint的数据流程:

大数据理论篇 No.5-聊聊Flink中的Checkpoint和Savepoint

Checkpoint是在所有任务处理完所有的等量的原始输入后,对全部任务状态进行的一个拷贝,它执行的过程大致如下:

  1. 暂停接收所有输入流。

  2. 等待处理完已经流入系统的数据,生成最新的状态。

  3. 将所有任务的状态拷贝到远程持久化存储,在所有任务完成拷贝后,生成全局一致性检查点。

  4. 恢复所有算子数据流的输入。

Checkpoint的作用,当然是为了保证故障之后可以恢复,那么我们来看一下checkpoint的恢复步骤,恢复的过程大致如下:

  1. 重启整个应用。

  2. 利用最新的checkpoint重置所有任务的状态。

  3. 恢复所有任务的处理。

数据源的恢复取决于消费的外部系统是否支持相关操作:重置消费;而对于sink端外部存储的恢复则需要分两阶段进行提交,详情可以查看笔者之前的文章:[大数据理论篇 No.3-看看Flink如何实现端到端的Exactly-once语义]。

这里再多一嘴:checkpoint的生成是根据用户设置,由Flink自动完成。

 

第2章 Savepoint

在任何一个系统中,都避免不了系统的迭代升级、BUG修复、环境升级等等操作,而在流计算当中,面对数据不断的涌入,Flink是如何实现这些操作,又避免影响系统的正常使用呢?这就是savepoint

Flink当中savepoint可以理解为checkpoint的特殊用途,原则上savepoint和checkpoint的生成算法完全一样,所以Savepoint可以看成包含一些额外元数据的特殊checkpoint。而Savepoint的生成时机和checkpoint有所不同,savepoint的生成不是由Flink自动完成,而实用户根据需要手动触发。

那么Savepoint在什么场景下使用呢:

  1. 作业Bug修复:Flink可以从savepoint启动一个与之前作业不同,但相互兼容的应用。这就意味着用户可以通过savepoint来将修复Bug后的程序更新到集群中。需要注意修复后的作业应用和sacepoint必须是兼容的,只有这样作业才能加载保存点内的state。

  2. 扩缩容:Flink通过savepoint启动新作业时,支持使用不同的并行度启动原作业,从而实现应用的扩缩容。

  3. Flink版本升级:当用户需要升级Flink版本时,也可以通过savepoint来进行迁移。

  4. 更换集群设备或数据中心。

  5. 归档/备份。

关于作业升级问题,要注意一点:升级后的算子节点可能发生变化,可能有新增和删除节点。这个时候savepoint如何能正确的将state分配给它对应的算子呢?其实,Flink首先会给每个算子分配一个唯一标识,如果应用在savepoint恢复之前发生过改动,恢复时会根据算子的唯一标识进行映射。但是Flink默认的唯一标识,会随着前置算子的增加或者删除而发生变化,所以官方建议用户手工指定算子的唯一标识,不要使用Flink默认分配的标识。从而使savepoint恢复时能够准确的将state恢复到原有算子上。