大话Flink之九- Flink的容错机制

目录

Flink 的容错机制

1 一致性检查点(Checkpoints)

 2 检查点的实现算法

3 保存点(Savepoints)

4 选择一个状态后端(state backend)


Flink 的容错机制

Flink 具体如何保证 exactly-once 呢? 它使用一种被称为"检查点"(checkpoint) 的特性,在出现故障时将系统重置回正确状态。下面通过简单的类比来解释检查点 的作用。

假设你和两位朋友正在数项链上有多少颗珠子,如下图所示。你捏住珠子,边 数边拨,每拨过一颗珠子就给总数加一。你的朋友也这样数他们手中的珠子。当你 分神忘记数到哪里时,怎么办呢? 如果项链上有很多珠子,你显然不想从头再数一 遍,尤其是当三人的速度不一样却又试图合作的时候,更是如此(比如想记录前一分 钟三人一共数了多少颗珠子,回想一下一分钟滚动窗口)。

于是,你想了一个更好的办法: 在项链上每隔一段就松松地系上一根有色皮筋, 将珠子分隔开; 当珠子被拨动的时候,皮筋也可以被拨动; 然后,你安排一个助手, 让他在你和朋友拨到皮筋时记录总数。用这种方法,当有人数错时,就不必从头开 始数。相反,你向其他人发出错误警示,然后你们都从上一根皮筋处开始重数,助 手则会告诉每个人重数时的起始数值,例如在粉色皮筋处的数值是多少。

Flink 检查点的作用就类似于皮筋标记。数珠子这个类比的关键点是: 对于指定 的皮筋而言,珠子的相对位置是确定的; 这让皮筋成为重新计数的参考点。总状态 (珠子的总数)在每颗珠子被拨动之后更新一次,助手则会保存与每根皮筋对应的检 查点状态,如当遇到粉色皮筋时一共数了多少珠子,当遇到橙色皮筋时又是多少。 当问题出现时,这种方法使得重新计数变得简单。

1 一致性检查点(Checkpoints)

• Flink 故障恢复机制的核心,就是应用状态的一致性检查点。我们其实不需要保存数据,kafka一般保存着数据,我们只要保存当前数据处理到哪里,所有处理完数据的状态。
• 有状态流应用的一致检查点,其实就是所有任务的状态,在某个时间点的一份拷贝(一份快照);这个时间点,不是处理时间意义上的时间点,而是应该是所有任务都恰好处理完一个相同的输入数据的时候。

当前这个图中,处理的数据就是1234567,进来之后,首先有一个source任务读取数据,source里面保存着一个当前读取的偏移量状态,防止发生故障以后,读取的偏移量在哪里;然后接下来进行的操作是求和,有两个求和任务,上面是偶数求和,下面是奇数求和,我要将5保存下来,那也必须保存下来所有任务处理完5这个状态。所以5,6,9保存下来。jobmanager保存着元信息,得知道storage中保存的谁是谁!

  • 在执行流应用程序期间,Flink 会定期保存状态的一致检查点。

  • 如果发生故障, Flink 将会使用最近的检查点来一致恢复应用程序的状态,并重新启动处理流程。

接下来是6,偶数求和那里加上了6变成了12,奇数不变,到了7的时候,7还在路上的时候奇数求和就挂掉了,挂掉了之后接下来需要重新启动应用,从检查点里加载状态。

• 遇到故障之后,第一步就是重启应用(1.9之后可以区域重启,不需要都重启

• 第二步是从 checkpoint 中读取状态,将状态重置
• 从检查点重新启动应用程序后,其内部状态与检查点完成时的状态完全相同

• 第三步:开始消费并处理检查点到发生故障之间的所有数据
• 这种检查点的保存和恢复机制可以为应用程序状态提供“精确一次”(exactly-once)的一致性,因为所有算子都会保存检查点并恢复其所有状 态,这样一来所有的输入流就都会被重置到检查点完成时的位置

 2 检查点的实现算法

• 一种简单的想法
  —— 暂停应用,保存状态到检查点,再重新恢复应用

• Flink 的改进实现
  —— 基于 Chandy-Lamport 算法的分布式快照
  —— 将检查点的保存和数据处理分离开,不暂停整个应用

 Flink 检查点算法

➢ 检查点分界线(Checkpoint Barrier)

  • Flink 的检查点算法用到了一种称为分界线(barrier)的特殊数据形式,用来把一条流上数据按照不同的检查点分开

  • 分界线之前到来的数据导致的状态更改,都会被包含在当前分界线所属的检查点中;而基于分界线之后的数据导致的所有更改,就会被包含在之后的检查点中

• 现在是一个有两个输入流的应用程序,用并行的两个 Source 任务来读取

   

• JobManager 会向每个 source 任务发送一条带有新检查点 ID 的消息,通过这种方式来启动检查点

  • 数据源将它们的状态写入检查点,并发出一个检查点 barrier

  • 状态后端在状态存入检查点之后,会返回通知给 source 任务,source 任务就会向 JobManager 确认检查点完成

• 分界线对齐:barrier 向下游传递,sum 任务会等待所有输入分区的 barrier 到达

• 对于barrier已经到达的分区,继续到达的数据会被缓存

• 而barrier尚未到达的分区,数据会被正常处理

• 当收到所有输入分区的 barrier 时,任务就将其状态保存到状态后端的检查点中, 然后将 barrier 继续向下游转发

• 向下游转发检查点 barrier 后,任务继续正常的数据处理

• Sink 任务向 JobManager 确认状态保存到 checkpoint 完毕
• 当所有任务都确认已成功将状态保存到检查点时,检查点就真正完成了

3 保存点(Savepoints)

• Flink 还提供了可以自定义的镜像保存功能,就是保存点(savepoints)

• 原则上,创建保存点使用的算法与检查点完全相同,因此保存点可以认为就是具有一些额外元数据的检查点

• Flink不会自动创建保存点,因此用户(或者外部调度程序)必须明确地触发创建操作

• 保存点是一个强大的功能。除了故障恢复外,保存点可以用于:有计划的手动备份,更新应用程序,版本迁移,暂停和重启应用,等等

4 选择一个状态后端(state backend)

1)MemoryStateBackend

内存级的状态后端,会将键控状态作为内存中的对象进行管理,将它们存储 在 TaskManager 的 JVM 堆上;而将 checkpoint 存储在 JobManager 的内存中。

2)FsStateBackend 

将 checkpoint 存到远程的持久化文件系统(FileSystem)上。而对于本地状 态,跟 MemoryStateBackend 一样,也会存在 TaskManager 的 JVM 堆上。

3)RocksDBStateBackend

将所有状态序列化后,存入本地的 RocksDB 中存储。 注意:RocksDB 的支持并不直接包含在 flink 中,需要引入依赖:

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-statebackend-rocksdb_2.12</artifactId>
    <version>1.10.1</version>
</dependency>

设置状态后端为 FsStateBackend,并配置检查点和重启策略:

 //1.设置状态后端
        env.setStateBackend(new MemoryStateBackend());
        env.setStateBackend(new FsStateBackend(""));
        env.setStateBackend(new RocksDBStateBackend());

        //2.检查点配置
        env.enableCheckpointing(300);

        //高级选项
        env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
        env.getCheckpointConfig().setCheckpointTimeout(60000L);
        env.getCheckpointConfig().setMaxConcurrentCheckpoints(2);//设置最大并行的检查点
        env.getCheckpointConfig().setMinPauseBetweenCheckpoints(100L);//设置两检查点之间的最小间隔,前一次checkpoint保存结束到下一次checkpoint触发开始这期间小于多少时间间隔,
                                                                      // 限制了checkpoint之间必须留下一段空闲时间,这段空闲时间用来正常处理数据,同时在做的checkpoint的数量只能有1个
        env.getCheckpointConfig().setPreferCheckpointForRecovery(true);//更倾向于用检查点来做恢复(默认是false)
        env.getCheckpointConfig().setTolerableCheckpointFailureNumber(0);//容忍检查点失败的次数,默认是0:代表着checkpoint挂了,那么整个任务也挂了

        //3.重启策略的配置
        //固定延迟重启(尝试重启次数,延迟时间)
        env.setRestartStrategy(RestartStrategies.fixedDelayRestart(3,10000L));
        //失败率重启
        //failureRateRestart(int failureRate:在一定的时间内统计到底重启了几次,也就是说,我只允许他在一定的时间范围内重启过几次我就不允许他重启了
        // , Time failureInterval:失败的时间间隔, Time delayInterval:连续的重启的这几次的时间间隔)
        env.setRestartStrategy(RestartStrategies.failureRateRestart(3, Time.minutes(10),Time.minutes(1));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值