这是我参与「第四届青训营 」笔记创作活动的的第4天
本节课主要讲了Exactly-Once在Flink中的应用,包括数据流和动态表、快照制作流程、端到端的实现以及相关案例。
回顾:
| 批式计算 | 流式计算 |
|---|---|
| 离线计算,非实时 | 实时计算,快速低延迟 |
| 静态数据集 | 无限流、动态、无边界 |
| 小时/天等周期性计算 | 持续运行 |
| 流批一体 |
1. 数据流和动态表
-
随处可见的流式数据:银行,GPS,物联网
-
SQL和流处理
| SQL | 流处理 |
|---|---|
| 表是有界的 | 流是无限元组序列 |
| 执行查询可以访问完整数据 | 无法访问完整数据 |
| 产生固定大小结果后终止 | 查询结果不断更新,永不终止 |
-
Stream -> Dynamic Table -> Continuous Queue -> Dynamic Table -> Stream
(表和流可以动态转换)
连续查询:从不终止,不断更新
-
动态表也可以看作静态表
-
两个连续查询对比:第一个查询更新之前的输出结果;第二个查询只附加到结果表(因为时间没有重合)
-
Retract : 回撤消息
-
-
查询出现故障?
- At-most-once:啥也不做
- At-least-once:保证数据不丢失,可能存在重复消费
- Exactly-once:有且只消费一次
2. Exactly-Once 和 Checkpoint
-
状态快照与恢复:事故发生时,回到发生前的状态
-
制作快照的时间点
- 不能在任意时间点,需要等待所有逻辑消费完成source保留状态及之前的数据
-
Chandy-Lamport算法
(1)每一个算子都接收到JM发送的Checkpoint Barrier标识状态快照制作的开始
(2)保存状态,向所有下游发送Checkpoint
(3)Barrier Alignment:算子等待所有barrier到达后才会开始,到达时间可能有先后
(4)快照制作和处理数据的解耦
(5)所有算子都告知JM状态制作完成,整个Checkpoint就结束
- 影响
(1)解耦了过程,不用等下游算子完成
(2)增加数据处理延迟
(3)保留到远端可能极为耗时
3. 端到端 Exactly-Once 实现
-
语义
-
两阶段提交协议
事务性:要么全都执行,要么全都不执行
协作者 & 参与者
(1)预提交阶段
- 协作者向所有参与者发生commit消息
- 收到消息执行事务
- 执行成功,vote yes;失败,vote no
(2)提交阶段
若vote yes:发送commit消息,真正执行,释放资源,向协作者发送ack消息
若vote no:发送rollback,向协作者发送ack消息,收到消息,完成回滚
-
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,下游数据不丢不重;增强的去重能力