Flink 状态一致性

Flink 状态一致性

  • 端到端精确一次
    • 输入端
    • 输出端
      • 预写日志
      • 两阶段提交

状态一致性有三种级别:

  • 最多一次 (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) : 事务随着检查点 , 提交或回滚

事务写入的思想 :

  1. 事务控制数据向外部系统的写入 , 并与检查点绑定
  2. 当 Sink 任务遇到 barrier 时,就保存状态, 并开启一个事务
  3. 当当前检查点保存完毕,就提交事务
  4. 当出现故障,状态就回退到上个检查点,事务也回滚

事务写入的俩个实现方式 :

  • 预写日志 (write-ahead-log , WAL)
  • 两阶段提交 (two-phase-commit , 2PC) : 先预提交 , 等检查点完毕 , 再正式提交

预写日志

预写日志 (WAL) 的实现步骤 :

  1. 先把结果数据作为日志 (log) 状态保存
  2. 在检查点保存时,也将结果数据一起持久化存储
  3. 当收到检查点完成的通知时,再将所有结果一次性写入外部系统
  4. 当写入所有数据成功后,再次确认相应的检查点,并将确认信息进行持久化保存

缺点 :

  • 一次性写入 , 有些性能问题
  • 再次确定时出现故障 , 会导致重复写入

两阶段提交

实现步骤 :

  1. 当第一条数据到, 或收到检查点的分界线时,Sink 就启动事务
  2. 所有数据写入 , 但事务未提交,都是 预提交 状态
  3. 当 Sink 任务收到检查点完成时,就提交事务
  4. 当出故障 , 当前事务就回滚 , 写入数据就撤回

2PC 对外部系统的要求 :

  • 外部系统要提供事务支持,或 Sink 任务能模拟外部系统上的事务
  • 检查点的间隔时,能开启事务 , 并接受数据写入
  • 在收到检查点完成之前,都是等待提交状态
  • Sink 任务, 能在进程失败后 , 恢复事务
  • 提交事务要幂等 : 事务的重复提交是无效的

你可能感兴趣的:(Flink,flink,kafka,java,大数据,数据库,缓存,分布式)