Flink的容错机制和一致性详解

Flink的容错机制和一致性详解

一. 容错机制

Flink 实现容错主要靠强大的CheckPoint机制和State机制。Checkpoint 负责定时制作分布式快照、对程序中的状态进行备份;State 用来存储计算过程中的中间状态。

1 检查点

1.1 一致性检查点

其实就是所有任务的状态,在某个时间点进行的一份快照
比如在所有任务都敲好处理完一个相同的输入数据的时候.

flink会定期的保存状态的一致检查点.

如果发生故障,这回使用最近的检查点来一致恢复应用程序的状态.

步骤:
1.重启
2.从检查点读取状态,
3.开始消费检查点到发生故障之间的所有数据.
1.2 检查点算法Chandy-Lamport

流程:

首先由JobManager将带有检查点ID的barrier发送到所有source中来开启检查点.
source将当前状态写入检查点.状态通知source完成,后source告知JonManager检查点完成并将barrier发送到下游所有的分区中.
下游的算子收到上游一个分区barrier后,将其保存,并将其后发来的数据进行保存,其他上游发来的数据正常计算,直到收到所有输入分区的barrier到达后将状态保存到检查点中,向JobManager报告,并将barrier发送到下游所有的分区中.
直到sink状态保存检查点后将成功信息发送到JobManager中,JobManager收到所有的成功报告后,向所有的位置发送状态保存完毕.
至此一次chandy-lamport完成.

JobManager 会向每个 source 任务发送一条带有新检查点 ID 的消息,通过这种方式来启动检查点.
barrier与普通数据记录相同,由算子处理,但不参与计算.当算子遇到barrier时将会触发检查点的相关行为.
数据源将它们的状态写入检查点,并发出一个检查点 barrier.
状态后端在状态存入检查点之后,会返回通知给 source 任务,source 任务就会向 JobManager 确认检查点完成.

检查点到达的三种状况:
->分界线对齐:barrier 向下游传递,sum 任务会等待所有输入分区的 barrier 到达
->对于barrier已经到达的分区,继续到达的数据会被缓存
->而barrier尚未到达的分区,数据会被正常处理
当收到所有输入分区的 barrier 时,任务就将其状态保存到状态后端的检查点中,然后将 barrier 继续向下游转发.
向下游转发检查点 barrier 后,任务继续正常的数据处理
Sink 任务向 JobManager 确认状态保存到 checkpoint 完毕
当所有任务都确认已成功将状态保存到检查点时,检查点就真正完成了

2.状态

概述:
1.由一个任务维护,并且用来计算某个结果的所有数据.
2.可以认为状态就是一个本地变量,可以被任务的业务逻辑访问.
3.flink会对状态进行管理.

2.1 算子状态
->列表状态.
->联名列表状态.
->广播状态.
2.2 键控状态

根据输入数据流中定义的key来维护和访问的.
每个分区内的每一个key都会维护一个状态实例.
当任务处理一条数据时,他会自动将状态的访问范围限定为当前数据的key.

->值状态(Value State)
->列表状态(List State)
->映射状态(Map State)
->聚合状态(Reducing State&Aggregating State)
3.3 状态后端

每传入一条数据,有状态的算子任务都会读取和更新状态.
状态后端主要负责两件事:本地的状态管理,以及将检查点(checkpoint)状态写入远程存储

->MemoryStateBackend
内存级的状态后端,会将键控状态作为内存中的对象进行管理,将它们存储在 TaskManager 的 JVM 堆上,而将 checkpoint 存储在 JobManager 的内存中
特点:快速、低延迟,但不稳定
->FsStateBackend
将 checkpoint 存到远程的持久化文件系统(FileSystem)上,而对于本地状态,跟 MemoryStateBackend 一样,也会存在 TaskManager 的 JVM 堆上
同时拥有内存级的本地访问速度,和更好的容错保证
->RocksDBStateBackend
将所有状态序列化后,存入本地的 RocksDB 中存储。

二. 一致性

Flink的一个重大价值在于,它既保证了exactly-once,也具有低延迟和高吞吐的处理能力。

每一个组件都保证了它自己的一致性,整个端到端的一致性级别取决于所有组件中一致性最弱的组件

在流处理中,一致性可以分为3个级别:

	at-most-once: 这其实是没有正确性保障的委婉说法——故障发生之后,计数结果可能丢失。同样的还有udp。
	at-least-once: 这表示计数结果可能大于正确值,但绝不会小于正确值。也就是说,计数程序在发生故障后可能多算,但是绝不会少算。
	exactly-once: 这指的是系统保证在发生故障后得到的计数结果与正确值一致。

需要保证,这一批数据要么全部成功,要么全部失败.

1. 三个组件

	内部保证 —— 依赖checkpoint
	source 端 —— 需要外部源可重设数据的读取位置
	sink 端 —— 需要保证从故障恢复时,数据不会重复写入外部系统
1.1. sink的两种方式

 幂等写入
所谓幂等操作,是说一个操作,可以重复执行很多次,但只导致一次结果更改,也就是说,后面再重复执行就不起作用了。
 事务写入
需要构建事务来写入外部系统,构建的事务对应着 checkpoint,等到 checkpoint 真正完成的时候,才把所有对应的结果写入 sink 系统中。

1.2 事务的两种方式

预写日志(WAL)和两阶段提交(2PC)。DataStream API 提供了GenericWriteAheadSink模板类和TwoPhaseCommitSinkFunction 接口,可以方便地实现这两种方式的事务性写入。

预写日志(WAL)
1.把结果数据先当成状态保存,然后在收到 checkpoint 完成的通知时,一次性写入 sink 系统
2.简单易于实现,由于数据提前在状态后端中做了缓存,所以无论什么 sink 系统,都能用这种方式一批搞定
3.DataStream API 提供了一个模板类:GenericWriteAheadSink,来实现这种事务性 sink
两阶段提交(2pc):
1.对于每个 checkpoint,sink 任务会启动一个事务,并将接下来所有接收的数据添加到事务里
2.然后将这些数据写入外部 sink 系统,但不提交它们 —— 这时只是“预提交”
3.当它收到 checkpoint 完成的通知时,它才正式提交事务,实现结果的真正写入
两阶段提交(2pc)对Sink系统的要求:
外部 sink 系统必须提供事务支持,或者 sink 任务必须能够模拟外部系统上的事务
在 checkpoint 的间隔期间里,必须能够开启一个事务并接受数据写入
在收到 checkpoint 完成的通知之前,事务必须是“等待提交”的状态。在故障恢复的情况下,这可能需要一些时间。如果这个时候sink系统关闭事务(例如超时了),那么未提交的数据就会丢失
ck时间要小于等待提交时间.
sink 任务必须能够在进程失败后恢复事务
提交事务必须是幂等操作

2. Flink + Kafka的一致性

Flink+Kafka 端到端状态一致性的保证实现:
source —— kafka consumer 作为 source,可以将偏移量保存下来,如果后续任务出现了故障,恢复的时候可以由连接器重置偏移量,重新消费数据,保证一致性
内部 —— 利用 checkpoint 机制,把状态存盘,发生故障的时候可以恢复,保证内部的状态一致性
sink —— kafka producer 作为sink,采用两阶段提交 sink,需要实现一个 TwoPhaseCommitSinkFunction

1.第一条数据来了之后,开启一个 kafka 的事务(transaction),正常写入 kafka 分区日志但标记为未提交,这就是“预提交”
2.jobmanager 触发 checkpoint 操作,barrier 从 source 开始向下传递,遇到 barrier 的算子将状态存入状态后端,并通知 jobmanager.(状态后端默认是内存级别的,可以改为文件级进行持久化保存.)
3.sink 连接器收到 barrier,保存当前状态,存入 checkpoint,通知 jobmanager,并开启下一阶段的事务,用于提交下个检查点的数据
4.jobmanager 收到所有任务的通知,发出确认信息,表示 checkpoint 完成
5.sink 任务收到 jobmanager 的确认信息,正式提交这段时间的数据
6.外部kafka关闭事务,提交的数据可以正常消费了。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值