这是我参与「第四届青训营 」笔记创作活动的的第3天。
一.数据流和动态表
1.传统SQL和流处理
2.流表转换
3.连续查询
- 查询从不停止
- 查询结果会不断更新,产生一个新的动态表
4.查询产生仅追加数据的动态表
TUMBLE window为时间窗口,本例中为1小时
5.两种查询对比
- 第一个查询更新先前输出的结果,即定义结果表的changelog流包含INSERT和UPDATE操作
- 第二个查询只附加到结果表,即结果表的changelog流只包含INSERT操作。
6.将动态表转换成流
与常规的数据库表一样,动态表可以通过插入(Insert)、更新(Update)和删除(Delete)更改,进行持续的修改。将动态表转换为流或将其写入外部系统时,需要对这些更改进行编码。Flink的Table API和SQL支持三种方式对动态表的更改进行编码:
- 仅追加(Append-only)流
仅通过插入(Insert)更改,来修改的动态表,可以直接转换为“仅追加”流。这个流中发出的数据,就是动态表中新增的每一行。
- 撤回(Retract)流
Retract流是包含两类消息的流,添加(Add)消息和撤回(Retract)消息。
- Upsert(更新插入)流
Upsert 流包含两种类型的消息:Upsert 消息和 delete 消息。转换为 upsert 流的动态表,需要有唯一的键(key)。
通过将 INSERT 和 UPDATE 更改编码为 upsert 消息,将DELETE更改编码为DELETE消息,就可以将具有唯一键(Unique Key)的动态表转换为流。
需要注意的是,在代码里将动态表转换为DataStream时,仅支持 Append 和Retract流 。而向外部系统输出动态表的TableSink接口,则可以有不同的实现,比如ES,就可以有Upsert模式。
7.不同数据处理保证的语义
-
At-most-once:出现故障的时候,啥也不做。数据处理不保证任何语义,处理时延低(对数据准确性要求不高,数据量大的场景)
-
At-least-once:保证每条数据均至少被处理一次,一条数据可能存在重复消费。(这种方式银行账单可能重复计费)
-
Exactly-once:最严格的处理语义,从输出结果来看,每条数据均被消费且仅消费一次,仿佛故障从未发生。
二.Exactly—once和Checkpoint
1.状态快照及恢复
对一系列数字流进行运算,三个计算逻辑也就是三个计算算子,第一个算子是source对数据流进行读取,第二个是sum_even就是对偶数进行累加,称为偶数累加器,sum_odd是对奇数进行累加,奇数累加器。
某一时刻对状态进行备份,保存当前的累加状态和是多少,三个计算算子都有状态,在数据读到5时,记录消费数据位点,保存当前的累加和。偶数累加器累加到6,奇数累加器累加到9了,存储需要永不丢失,可靠。继续后面的数据消费,消费到6没有问题,消费到7时,奇数累加器故障了,导致整个作业挂掉了。故障恢复后,重启作业,拿最近的故障恢复时间点,就是消费到5这个节点,把数据恢复到算子当中去,回拨数据流,从一个历史的5后面6开始消费,保证数据不丢不重。