Flink 容错机制

一、 检查点check point

        简单理解:平时写word时突然蓝屏死机了,出现故障,如果没有检查点,相当于word没有做保存。

        Flink中就是用存档的思路,把某个时间点的状态保存下来,就是检查点,他的作用就是为了故障恢复

1.1 检查点的保存

1)周期性的触发保存

        Flink中,检查点的保存是周期性触发的,间隔时间可以进行设置

2)保存的时间点

        应该在所有算子恰好处理完一个相同的输入数据时,把他们的状态保存下来

1.2 从检查点恢复状态

        发生故障时,就需要找到最近一次成功保存的检查点来恢复状态

流程:重启应用,任务状态会清空 -> 读取检查点,重置状态 -> 重置偏移量(从记录的位置重新读数据) -> 继续处理数据

1.3 检查点算法 

        Flink中, 采用了基于Chandy-lamport算法的分布式快照,特点是可以不暂停整体流程流处理的前提下,将状态备份保存到检查点

1.3.1 检查点分界线(Barrier)

        类似于水位线:提取事件时间,经过计算生成一条水位线插入数据。

        在数据流的source中插入一条特殊的数据结构,专门用来表示触发检查点保存的时间点。随着数据流走,到哪哪就进行持久化快照保存。也就是某一个节点接收到barrier,就要对自身的状态做备份,到远端的持久化存储

 1.3.2 分布式快照算法(Barrier对齐的精确一次)

         watermark表示"之前的数据都到期了",而barrier表示"之前所有数据的状态更改保存入当前检查点"。谁遇到barrier,谁就已经处理完barrier之前的数据了,然后保存进检查点

        当处理多个分区的传递时,Flink使用了Chandy-lamport算法的变体,被称为"异步分界线快照算法",核心为两个原则

        1)  当上游任务向多个并行下游任务发送barrier时,需要广播出去

        2)而当多个上游任务向同一个下游任务传递分界线时,需要在下游任务执行"分界线对齐"操作,也就是需要等所有并行分区的barrier到齐,才可以开始状态的保存。

检查点具体过程:

        1. 周期性JobManager向source发送barrier,source中插入一个分界线,并将偏移量持久化存储,每一个任务保存过后会向JobManager返回一个ack确认。

        2.  barrier也继续向下走广播,分界线对齐

        3.  有状态的算子将状态保存至持久化

        4.  先处理缓存数据,然后再正常处理

(补充) 由于分界线对齐需要先到达分区的数据做缓存等待,一定程度上可能会影响处理的速度。当出现背压时,下游任务会堆积大量的缓冲数据,检查点可能需要很久才可以保存完毕

        为了应对这种场景,flink1.11之后提供了不对齐检查点的保存方式,可以将未处理的数据也保存到检查点

1.3.3 分布式快照算法(Barrier对齐的至少一次)

        barrier后的数据越过了barrier,并且也更新了状态,等到barrier对齐了,才做快照备份。一旦flink程序发生故障,要重新读重新计算,造成结果出错

精准一次:barrier后面的数据阻塞,不能越过barrier;

至少一次:后面的数据继续计算

1.3.4 非Barrier对齐的精准一次

        在Barrier对齐期间,后续的数据需要阻塞等待,越对齐可能越加剧反压

每个任务节点的前后都是有输入输出缓冲区的,数据先进入输入缓冲区,然后处理,之后到输出缓冲区

barrier会进行跳跃。当一个任务的第一个barrier到达输入缓冲区时,这个任务之前的数据已经被持久化过,这个barrier就会跳到输出缓冲区,并标记被barrier越过的输入缓冲区和输出缓冲区的数据和其他barrier之前的数据。然后把标记数据和状态一起保存到checkpoint中,从checkpoint恢复时这些数据也会一起恢复到对应位置

1.3.5 总结

Barrier对齐: 一个task收到 所有上游 同一个编号的barrier之后,才会对自己的本地状态做备份

        ①:精准一次:在对齐过程中,barrier后面的数据 阻塞等待,不会越过barrier

        ②:至少一次:在对齐过程中,先到的barrier,其后面的数据不阻塞,继续计算

非Barrier对齐:一个Task收到第一个barrier后,就开始执行备份,能保证精准一次。细节:

        ①:先到的barrier 将本地状态备份,同时后面的数据接着计算输出。

        ②:未到的barrier,其前面的数据接着计算输出,同时 也保存到备份中

        ③:最后一个barrier到达task时,这个task结束

1.4 检查点配置

        1. 默认是关闭的,开启需要开启enableCheckpointing方法,传入long类型的时间戳和模式(默认是精准一次,也就是barrier对齐的)

        2. 检查点的存储位置可以配置,默认是JobManager的堆内存中的。可以设置停止程序后是否删除检查点

        3. 超时时间,指定检查点的保存时间,超时没完成就会被丢弃掉,默认是十分钟

        4. 最大并发检查点数量:同时运行中的checkpoint最大并发数

        5. 最小等待间隔:上次轮checkpoint结束到下一轮checkpoint开始之间的间隔,设置了>0,默认并发为1

        6. 开启非对齐检查点,会自动设为精准一次,并发为1

ps: 开启非对齐检查点,默认时间为0,表示一开始就用非对齐检查点。如果设置超时时间大于0,则刚开始使用的是barrier对齐,当对齐时间超过了这个参数,自动切换成非对齐检查点

        7. 通用增量checkpoint(changelog)

会将变更的增量数据同步到checkpoint,不是全量更新

流程

        ①:带状态的算子任务会将状态写入到changelog中,同时checklog会持续的向远端的checkpoink上传。同时还有一个状态表是记录最新结果的

        ②:状态表定期的保存,是独立于检查点的(状态物化)

        ③:状态物化完成之后,changelog就会截断到相应的点

1.5 保存点(SavePoint)

        理解:也是一个存盘的备份,他的原理和算法与检查点完全相同,和检查点最大的区别就是触发的时机不同

1. 和检查点的区别

①:检查点是由Flink自动管理的,定期创建,发生故障之后自动读取进行恢复

        保存点不会自动创建,必须由用户手动触发保存操作

②:保存点比检查点多了一些元数据

1.6 状态一致性

1.6.1 一致性的概念和级别

        最多一次:对于Flink来讲,不开启checkpoint,就是最多一次

        至少一次:开启barrier对齐,barrier后面的数据也会接着处理,也会存状态,恢复之后,越过barrier的数据还要被重新读取,重新计算

        精准一次:barrier对齐,且对齐期间,barrier后面的数据阻塞,等到对齐完,之后的数据才能接着处理

1.6.2 端到端的一致性

        能否达到至少一次,要看数据源能够重放数据。要达到精准一次,要考虑数据源、流处理器、外部存储都要有相应的保证机制

1. 输入端

        数据可重放,比如kafka,可重置读取数据的偏移量

2. 流处理器

        Flink处理,开启checkpoint(barrier对齐的精准一次,非barrier对齐的精准一次)

3. 输出端

        幂等(执行多次和执行一次是一样的)或事务(要么成功要么失败),幂等:利用mysql的主键upsert hbase的rowkey唯一。事务(外部系统提供):两阶段提交写kafka,两阶段提交写Mysql(XA事务)

        比如现在写数据1 2 3 | 4 5 ,到5执行失败,checkpoint重新执行4,但是外部系统已经把4写入

事务写入

        两种方式,预写日志(WAL),两阶段提交(2PC)

1. 预写日志

        ①:先把结果作为日志状态保存起来

        ②:进行检查点保存时,把这些数据也保存起来

        ③:在收到检查点完成的通知后,一批次的将数据写入外部系统

        ④:成功写入数据后,在内部再次确认相应的检查点,外部系统会返回一个ack,确认成功写入,将确认信息也会持久化保存

问题:当数据成功写入外部系统,内部内部检查点已成功保存,但是没有收到ack,这时flink还会认为没有成功写入。发生故障后需要退回到上一次,会导致这批数据的重复写入

2. 两阶段提交

        主要是用来解决分布式场景下的事务,分为预提交和正式提交

预提交:上一次检查点完成,barrier后续的数据开始进行 预提交(sink多个子任务都在往外写)

正式提交:当新的检查点完成时,各个节点正式提交

当barrier后面的数据失败了,会进行回滚 

ps:Kafka -> Flink -> Kafka -> 下游

        如果下游消费者隔离级别设置为读未提交(默认),预提交的数据也会被读到,整个链路端到端的精准一次,下游的消费者,需要设置为读已提交

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值