Exactly-Once语义在Flink中的实现 | 青训营笔记

114 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的的第4天

本节课主要讲了Exactly-Once在Flink中的应用,包括数据流和动态表、快照制作流程、端到端的实现以及相关案例。

回顾:

批式计算流式计算
离线计算,非实时实时计算,快速低延迟
静态数据集无限流、动态、无边界
小时/天等周期性计算持续运行
流批一体

1. 数据流和动态表

  1. 随处可见的流式数据:银行,GPS,物联网

  2. SQL和流处理

SQL流处理
表是有界的流是无限元组序列
执行查询可以访问完整数据无法访问完整数据
产生固定大小结果后终止查询结果不断更新,永不终止
  1. Stream -> Dynamic Table -> Continuous Queue -> Dynamic Table -> Stream

    (表和流可以动态转换)

    连续查询:从不终止,不断更新

    • 动态表也可以看作静态表

    • 两个连续查询对比:第一个查询更新之前的输出结果;第二个查询只附加到结果表(因为时间没有重合)

    • Retract : 回撤消息

  2. 查询出现故障?

    • At-most-once:啥也不做
    • At-least-once:保证数据不丢失,可能存在重复消费
    • Exactly-once:有且只消费一次

2. Exactly-Once 和 Checkpoint

  1. 状态快照与恢复:事故发生时,回到发生前的状态

  2. 制作快照的时间点

    • 不能在任意时间点,需要等待所有逻辑消费完成source保留状态及之前的数据
  3. Chandy-Lamport算法

(1)每一个算子都接收到JM发送的Checkpoint Barrier标识状态快照制作的开始

(2)保存状态,向所有下游发送Checkpoint

(3)Barrier Alignment:算子等待所有barrier到达后才会开始,到达时间可能有先后

(4)快照制作和处理数据的解耦

(5)所有算子都告知JM状态制作完成,整个Checkpoint就结束

  1. 影响

(1)解耦了过程,不用等下游算子完成

(2)增加数据处理延迟

(3)保留到远端可能极为耗时

3. 端到端 Exactly-Once 实现

  1. 语义

  2. 两阶段提交协议

    事务性:要么全都执行,要么全都不执行

    协作者 & 参与者

(1)预提交阶段

  • 协作者向所有参与者发生commit消息
  • 收到消息执行事务
  • 执行成功,vote yes;失败,vote no

(2)提交阶段

若vote yes:发送commit消息,真正执行,释放资源,向协作者发送ack消息

若vote no:发送rollback,向协作者发送ack消息,收到消息,完成回滚

  1. Flink中的2PC Sink

    Coordinator                               Participant
                      Query to commit
                  ----------------------->    prepare*/abort*
                      Vote yes/no
    commit*/abort*<----------------------- 
                      commit/rollback
                  ------------------------>  commit*/abort*
                      acknowledgement
                  <------------------------
    end              
    

4. Flink案例讲解 —— 账单计算服务

从Kafka中读取账单消息,进行处理后写入MySQL中

存在的问题:非严格的Exactly-once(部分数据会严格写入);去重能力有限

Flink解决方案:严格的端到端Exactly-once,下游数据不丢不重;增强的去重能力