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

80 阅读3分钟

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

随着大数据的不断发展,流式数据在出现之后便迅速传播,到现在已经随处可见。

传统的SQL处理与流处理的对比:

特征SQL流处理
处理数据的有界性处理的表是有界的流是一个无界元组序列
处理数据的完整性执行查询可以访问完整的数据执行查询无法访问所有的数据
执行时间批处理查询产生固定大小结果后终止查询不断更新结果

敲重点!!! 数据流与动态表可以进行相互之间的转换:

1658978782405.png

其中,动态表的定义为:与表示批处理的静态表不同,动态表是随着时间变化的。可以像查询静态批处理表一样查询。数据库表的INSERT、UPDATE、DELETE DML语句的stream的结果,通常称为changelog stream。

动态表能够实现连续查询,在任何时候,连续查询的结果在语义上与以批处理模式在输入表快照上执行的相同查询的结果相同。(连续查询:1、查询从不终止;2、查询结果会不断更新,产生一个新的动态表。)

1658979207965.png

在查询过程中如果出现故障怎么办?

不同的数据处理保证的语义:

  • At-most-once:出现故障的时候,没有任何操作。数据处理不保证任何语义,处理时延低;
  • At-least-once:保证每条数据均至少被处理一次,一条数据可能存在重复消费;
  • Exactly-once:是最严格的处理语义,从输出结果来看,每条数据均被消费且仅消费一次,仿佛故障从来没发生过。

Excatly-Once和Checkpoint

Flink通过以下特性实现Exactly_Once:

  1. Source支持数据重读;
  2. Sink支持事务。可以是类似二阶段提交,如kafka,或者Sink支持幂等,可以覆盖之前写入的数据,如redis;
  3. 基于Checkpoint保证状态的容灾及一致性。

Checkpoint是Flink实现容错机制最核心的功能,它会根据用户的配置周期性地对流中各个算子(Operator)的状态生成快照,持久化到外部存储。Flink程序一旦意外崩溃时,重新运行程序时可以有选择地从这些快照进行恢复,从而修正因为故障带来的程序数据异常。Flink写入到外部存储是异步的,意味着Flink在这个阶段可以继续处理数据。

Checkpoint任务的执行

task.triggerCheckpointBarrier(checkpointId, checkpointTimestamp, checkpointOptions, advanceToEndOfEventTime);

总结

CheckPoint是个注册在JobManager上的定时任务,根据用户的配置定时异步的在TaskManager上执行。在TaskManager上执行时,首先生成一条CheckpointBarrier记录,将其BroadCast到下游流中,同时会执行CheckPoint任务,将State信息持久化到后端存储中。下游流收到CheckPointBarrier会阻塞输入(Exactly_Once语义时),如果下游有多条流的还会进行Barrier对齐,然后再执行上面的讲State信息持久化到后端存储这个动作。这便是这次学习的重点。

参考:

blog.csdn.net/zc19921215/…

blog.csdn.net/u012871914/…(流式处理术语解释 Exactly-once与Effectively-once)

blog.csdn.net/leileibest_…(Flink Graph)