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

85 阅读3分钟

这是我参与「第四届青训营 -大数据场」笔记创作活动的第5篇笔记

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

数据流与动态表

传统SQL和流处理

image.png

数据流和动态表转换

image.png

  1. Stream:数据流
  2. Dynamic Table:动态表
  3. Coutinuous Query:连续查询

流转化为表,通过动态查询,再由表转化为流

在流上定义表

动态表 与表示批处理数据的静态表不同,动态表是随时间变化的。可以像查询静态批处理表一样查询它们。

连续查询

  1. 查询从不终止
  2. 查询结果会不断更新,产生一个新的动态表

在任何时候,连续查询的结果在语义上与以批处理模式在输入表快照上执行的相同查询的结果相同。

不同数据处理保证的语义

  1. At-most-once:出现故障的时候吗,啥也不做。数据处理不保证任何语义,处理时延低
  2. At-least-once:保证每条数据均至少被处理一次,一条数据可能存在重复消费
  3. Exactly-once:最严格的处理语义,从输出结果来看,每条数据均被消费且仅消费一次,仿佛故障从未发生

Exactly-Once 和 Checkpoint

CheckPoint机制保证xactly-Once语义

状态快照与恢复

Flink容错机制的核心部分是制作分布式数据流和操作算子状态的一直想快照。这些快照充当一致性checkpoint,系统可以在发生故障时回滚。

image.png

  1. 第一个算子是Source,它负责读数据流
  2. sum_even:偶数累加器
  3. sum_odd:奇数累加器
  4. Storage:数据存储

制作快照的时间点

状态恢复的时间点

需要等待所有处理逻辑消费完成source保留状态及之前的数据

Chandy-Lamport算法

image.png

如图:

两个数据流对应两个source,并行独立处理,两个输出结果:统计偶数累加和以及奇数累加和。

快照制作的开始

image.png

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

JM协助管理快照制作的整个过程,第一步负责向每一个source发送Checkpoint Barrier,Checkpoint Barrier将数据流分开,将数据分成不同的数据段。

Source算子的处理

image.png

各个source保存自己状态后,向所有连接的下游继续发送Checkpoint Barrier,同时告知JM自己状态已经制作完成

当source收到Checkpoint Barrier之后,

  1. source会短暂停止自己的处理逻辑同时将当前的结果状态保存
  2. 向下游发送Checkpoint Barrier
  3. 以此类推

Barrier Alignment

image.png

如图,source1的Checkpoint Barrier,source2的Checkpoint Barrier未到达

  1. 算子会等待所有上游的barrier到达之后才开始快照的制作
  2. 已经制作完成的上游算子会继续处理数据,并不会被下游制作快照的过程阻塞

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

image.png

image.png

sink也会有相同的处理(同source),由于sink没有下游,只好通知JM已经完成

checkpoint的结束

image.png

所有算子都告知JM状态制作完成之后,整个checkpoint就结束了

Flink端到端的Exactly-once语义

端到端 Exactly-once 语义

image.png

  1. checkpoint能保证每条数据都对各个有状态的算子更新一次,sink输出算子仍然可能下发重复的数据
  2. 严格意义的端到端的Exactly-once语义需要特殊的sink算子实现

两阶段提交协议

(未完待续)