Flink到底能不能实现exactly-once语义?
导读:假设有这么一个场景 , Flink 在完成了一次 checkpoint 后 , 第二次 checkpoint 前(此时两个 checkpoint 中间的数据已经处理了一部分了)Job 出现异常挂掉了 。 当 Job 恢复时就会从上一次成功的 checkpoint 处恢复 。 那这个时候刚才被处理的数据又会被处理一次 , 那这就不能称为 exactly-once 语义了?这就是很多人存在疑惑的地方 , 下面我将从以下几个点展开讨论:
- Exactly-once 语义理解
- Flink 失败恢复依赖于检查点机制 + 可部分重放的数据源
- 场景分析
- 那Flink如何实现端到端的exactly-once
文章插图
Flink 失败恢复依赖于检查点机制 + 可部分重放的数据源可部分重放的数据源:这个很好理解 , 比如上游数据源是 kafka , 其支持从指定的 offest 处重新开始消费数据的 。
检查点机制:检查点是 Flink 中 Fault Tolerance 的核心机制 , 其会随着时间推移不断的做 Checkpointing , 不断的产生 snapshot(快照)存储到 Statebackend 中 , 快照里面记录了包括:
- 当前检查点开始时数据源(例如Kafka)中消息的offset
- 记录了所有有状态的operator当前的状态信息(例如sum中的数值)
Flink 提供了 Exactly once 特性 , 其通过 barrier 对齐后 , 进行checkpointing , 生成snapshot并持久化实现 。 Checkpointing 是 Flink 中 Fault Tolerance 的核心机制 , 关于详细的 Checkpointing 工作方式 , barrier 及如何做到 exactly-once 等可以查看 Flink中的Fault Tolerance 容错机制。
场景分析
文章插图
Flink任务失败恢复的时候状态恢复的过程
为了方便分析问题我们对场景进行简化 , 假设 kafka 的 partition 只有一个 , 并且 Kafka Source 流过来的所有数据都是,key 都是同一个"hello" 。 Job 中间有一个 operator 处理算子对相同的 Key 数据的值进行 Sum 计算 。
文章插图
1、当Job 在第一次进行 checkpoint 的时候 , 快照里面的状态是:
- <1,<0,10>> :表示 checkpoint 的 ID是1 , kafka 的 paritition 0 消费到的 offest 是10
- operator算子的状态是
3、接下来任务会从上一次成功的 checkpoint1 开始恢复 , 也就是说 kafka 的 offest 还是从10 开始 , 算子的状态则是恢复到。
4、接着进行数据处理 , 这个时候尽管部分数据会被重复消费多一遍 , 但算子的状态中 SUM 的结果是正确的 。 这是因为算子的状态也恢复到之前的状态了 , 所以对于状态来说确实是实现了 exactly-once语义. 。
结论:Flink 是支持 exactly-once 语义的 , 但其针对的是 Flink 应用内部的数据流处理(也就是Flink的状态state来说的) , 换句话说 , 事件的处理可以发生多次 , 但是该处理的结果只在持久化后端状态存储中反映一次 , Flink自身是无法保证端到端的exactly-once语义的 。
文章插图
- “滑向2022”新浪杯高山滑雪公开赛,与华为WATCH GT2 Pro一起雪战到底
- 一文读懂,书架箱和落地箱到底哪个好?
- Win10 真的要兼容安卓 App 了,微软到底想玩什么
- FlinkSQL 动态加载 UDF 实现思路
- 电脑开机那么难
- 20款游戏实战!酷睿i7-10750H、锐龙9 4900H到底谁更强?
- 手机出现“自动更新”,到底要不要更新?答案已确认
- 充电太快会爆炸吗?氮化镓到底有多火?
- 把手机屏幕换成绿色,到底能不能护眼?
- 将OPPO美学进行到底 Reno5 Pro+外观设计一览