这是我参与「第四届青训营 」笔记创作活动的的第3天
数据流和动态表
动态表和数据流是可以相互转换的。动态表会随时间变化,取某个时间点可以像静态表一样查询,结果与批处理相同。动态表还可以查询仅仅是追加结果的(类似于窗口的处理)。
端到端exactlyonce和ck的实现
流式场景的回撤概念(retract):当某个结果更新的时候,要先撤回下游的那个结果,再发送新的结果。
三种一致性保证语义: At-most-once:每条数据消费至多一次,处理延迟低。最简单,可能导致下游数据丢失,最大限度保证处理速度。 At-least-once:每条数据消费至少一次,一条数据可能存在重复消费 Exactly-once:每条数据都被消费且仅被消费一次,仿佛故障从未发生
barrier传递和ck JM会向数据流发送barrier,会随着数据流推进。多并行的下游算子要接收到所有的barrier才停止逻辑,保存快照,对barrier之前的数据进行保存状态。当一个算子的bar先到,在等其他算子时,数据又来了,这时候不会进行处理。barrier之后是下一个状态要保存的结果。当所有算子完成状态保存的时候,即完成了一次ck。
端到端的exactlyonce介绍:端到端的 Exactly once,是指作业结果正确且只会被产出一次,它的要求除了有可重放的 source 外,还要求有事务型的 sink 和可以接收幂等的产出结果。
两阶段提交协议:实现端到端的exactly once
两阶段提交协议的概念:
Coordinator:协作者,同步和协调所有节点处理逻辑的中心节点
Participant:参与者,被中心节点调度的其他执行处理逻辑的业务节点
在flink中JM是写作者,source算子sink是参与者。
所有的参与者都yes,就成功。
JM对应协作者,计算节点对应参与者
第一阶段的提交:协作者会向参与者发送commit消息,计算节点执行事务告诉JM该次状态制作是否成功。执行事务的结果成功,返回ack消息vote yes表示预提交成功。JM会向算子发送此次事务的消息消息,完成真正提交,下游才可以读取这次提交写入的数据。如果事务提交失败了,那这一批数据就会被标记为读取失败,下游的consumer读取的时候就会跳过被标记的数据,所有状态完成了才commit对下游可见。
案例
kafka-mysql方案不支持exactlyonce,只能支持atleast once,不同批处理可能出现重复数据。
flink写入mysql,支持事务,结合两阶段提交可以实现exactlyonce,可以在更长的时间实现去重。