状态一致性有三种级别:
- 最多一次 (AT-MOST-ONCE) : 只处理一次 , 遇到故障就会丢失 , 优点 : 处理快
- 至少一次 (AT-LEAST-ONCE) : 不会丢失数据 , 但存在重复数据
- 精确一次(EXACTLY-ONCE) : 不会丢失数据 , 也不会重复数据
实现要求 :
- 端到端 (end-to-end) 的状态一致性 : 数据源、流处理器、外部存储系统都要有保证机制
- at-least-once 级别 : 数据源能重放数据
端到端精确一次
端到端精确一次 (end-to-end exactly-once) 的关键点 :
- 输入端 : 数据能重放数据 (如 : Kafka)
- Flink 靠检查点机制 , 能实现
exactly-once
一致性语义 - 输出端 : 幂等 (主键) , 事务 (俩阶段提交)
输入端
输入端 :
- 要实现端到端一致性 , 要输入数据源能重放数据
socket/Kafka 区别 :
- socket : 当故障后 , 无法重新发 , 就会丢失数据
- kafak : 当故障后 , 能通过位点 , 重新获取数据 , 就能保证不丢失数据
输出端
要保证 exactly-once 一致性 , 需要输出支持 :
- 幂等写入 (idempotent) : 重复执行,只会导致一次结果修改 , 如 : Redis , MySQL 更新操作
- 事务写入 (transactional) : 事务随着检查点 , 提交或回滚
事务写入的思想 :
- 事务控制数据向外部系统的写入 , 并与检查点绑定
- 当 Sink 任务遇到 barrier 时,就保存状态, 并开启一个事务
- 当当前检查点保存完毕,就提交事务
- 当出现故障,状态就回退到上个检查点,事务也回滚
事务写入的俩个实现方式 :
- 预写日志 (write-ahead-log , WAL)
- 两阶段提交 (two-phase-commit , 2PC) : 先预提交 , 等检查点完毕 , 再正式提交
预写日志
预写日志 (WAL) 的实现步骤 :
- 先把结果数据作为日志 (log) 状态保存
- 在检查点保存时,也将结果数据一起持久化存储
- 当收到检查点完成的通知时,再将所有结果一次性写入外部系统
- 当写入所有数据成功后,再次确认相应的检查点,并将确认信息进行持久化保存
缺点 :
- 一次性写入 , 有些性能问题
- 再次确定时出现故障 , 会导致重复写入
两阶段提交
实现步骤 :文章来源:https://www.toymoban.com/news/detail-502298.html
- 当第一条数据到, 或收到检查点的分界线时,Sink 就启动事务
- 所有数据写入 , 但事务未提交,都是 预提交 状态
- 当 Sink 任务收到检查点完成时,就提交事务
- 当出故障 , 当前事务就回滚 , 写入数据就撤回
2PC 对外部系统的要求 :文章来源地址https://www.toymoban.com/news/detail-502298.html
- 外部系统要提供事务支持,或 Sink 任务能模拟外部系统上的事务
- 检查点的间隔时,能开启事务 , 并接受数据写入
- 在收到检查点完成之前,都是等待提交状态
- Sink 任务, 能在进程失败后 , 恢复事务
- 提交事务要幂等 : 事务的重复提交是无效的
到了这里,关于Flink 状态一致性的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!