这是我参与「第四届青训营 」笔记创作活动的的第3天。
本节课程主要分为 4 个方面:
1.数据流和动态表
2.Exactly-once 和 Checkpoint
3.Exactly-once实现
4.Flink案例讲解
一.数据流和动态表
1.2.传统的SQL和流处理
1). 处理数据的有界性:SQL:处理的表是有界的
流处理:流是一个无限元组序列
2). 处理数据的有界性:SQL:执行查询可以访问完整的数据
流处理:执行查询无法访问所有的数据
3). 处理数据的有界性:SQL:批处理查询产生固定大小结果后终止
流处理:查询不断更新结果,永不终止
1.3.在流上定义表
动态表:与表示批处理数据的静态表不同,动态表是随时间变化的。可以像查询静态批处理表一样查询它们。数据库表是INSERT、UPDATE和DELETE DML语句的stream的结果,通常称为changelog stream。
○ Append-only Stream: Append-only 流(只有INSERT消息)
○ Retract Stream:Retract流(同时包含INSERT消息和DELETE消息)
○ Upsert Stream:Upsert流(同时包含UPSERT消息和DELETE消息)
1.4.连续查询
1).查询从不终止
2).查询结果会不断更新,产生一个新的动态表
3).结果的动态表也可转换成输出的实时流
在任何时候,连续查询的结果在语义上与以批处理模式在输入表快照上执行的相同查询的结果相同。
1.6.两个连续查询对比
1).第一个查询更新先前输出的结果,即定义结果表的changelog流包含INSERT和UPDATE操作;
2).第二个查询只附加到结果表,即结果表的changelog流包含INSERT操作。
1.9.数据流和动态表转换回顾
■ 数据流和动态表之间的转换
■ 在数据流的查询不会终止
■ 查询可能会有状态,同来不断更新查询的结果
数据流和动态表的转换图
1.10.不同数据处理保证的语义
At-most-once:出现故障的时候,啥也不做。数据处理不保证任何语义,是,处理时延低;
At-least-once:保证每条数据均至少被处理一次,一条数据可能存在重复消费;
Exactly-once:最严格的处理语义,从输出结果来看,每条数据均被消费且消费一次,彷佛故障从未发生。
二.Exactly-once 和 Checkpoint
2.2.制作快照的时间点
状态恢复的时间点:需要等待所有处理逻辑消费完成source保留状态及之前的数据
一个简单的快照制作算法:
1).暂停处理输入的数据;
2).等待后续所有处理算子消费当前已经输入的数据;
3).待2处理完后,作业所有算子复制自己的状态并保存到远端可靠存储;
4).恢复对输入数据的处理。
2.3.Chandy-Lamport算法
2.3.1.快照制作的开始
每一个source算子都接收到JM发送的Checkpoint Barrier标识状态快照制作的开始。
2.3.2.Source算子的处理
各个source保存自己的状态后,向所有链接的下游继续发送Checkpoint Barrier,同时告知JM自己状态已经制作完成。
2.3.3.Barrier Alignment
✓ 算子会等待所有上游的barrier到达后才开始快照的制作;
✓ 已经制作完成的上游算子会继续处理数据,并不会被下游算子制作快照的过程阻塞。
2.3.5.chechpoint的结束
所有算子都告知JM状态制作完成后,整个Checkpoint就结束了。
2.4.Checkpoint对作业性能的影响
1).解耦了快照制作和数据处理过程,各个算子制作完成状态快照后就可以正常处理数据,不用等下游算子制作制作完成快照;
2).在快照制作和Barrier Alignment过程中需要暂停处理数据,仍然会增加数据处理延迟;
3).快照保存到远端也有可能极为耗时。
Checkpoint ACK和制作完成
三.Flink端到端的Exactli-once语义
两阶段提交协议
3.1.端到端的Exactli-once语义
1).Checkpoint能保证每条数据都对各个有状态的算子更新一次,sink输出算子仍然可能下发重复的数据;
2).严格意义的端到端的Exactli-once语义需要特殊的sink算子实现。
3.2.两阶段提交协议
3.2.1.两阶段提交协议(一)-预提交阶段
1).协作者向所有参与者发送一个commit消息;
2).每个参与的协作者收到消息后,执行事务,但是不是真正提交;
3).若事务成功执行完成,发送一个成功的消息(vote yes);执行失败,则发送一个失败的消息(vote no)。
3.2.2.两阶段提交协议(二)-提交阶段
◉ 若协作者成功接收到所有的参与者vote yes的消息
1).协作者向所有参与者发送一个commit消息;
2).每个收到commit消息的参与者释放执行事务所需的资源,并结束这次事务的执行;
3).完成步骤2后,参与者发送一个ack消息给协作者;
4).协作者收到所有参与者的ack消息后,标识该事务执行完成。
◉ 若协作者成功接收到所有的参与者vote no的消息(或者发生等待超时)
1).协作者向所有参与者发送一个rollback消息;
2).每个收到rollback消息的参与者回滚事务的执行操作,并释放事务所占资源;
3).完成步骤2后,参与者发送一个ack消息给协作者;
4).协作者收到所有参与者的ack消息后,标识该事务完成回滚。
3.4.Flink两阶段提交总结
(1.)事务开启:在sink task向下游写数据之前,均会开启一个事务,后续所有写数据的操作均在这个事务中执行,事务未提交前,事务写入的数据下游不可读;
(2.)预提交阶段:JobManager开始下发Checkpoint Barrier,当各个处理逻辑接收到barrier后停止处理后续数据,对当前状态制作快照,此时sink也不再当前事务下继续处理数据(处理后续的数据需要新打开下一个事务)。状态制作成功则向JM成功的消息,失败则发送失败的消息;
(3.)提交阶段:若JM收到所有预提交成功的消息,则向所有处理逻辑(包括sink)发送可以提交此次事务的消息,sink接受到此消息后,则完成此次事务的提交,此时下游可以读到这次事务写下的数据;若JM有收到预提交失败的消息,则通知所有处理逻辑回滚这次事务的操作,此时sink则丢弃这次事务提交的数据下。
四.Flink案列讲解
■ 账单计算服务
优势:1).严格意义上的端到端的Exactly-Once语义:下游读到的数据是不丢不重的;
2).增强的去重能力:可以在更长的时间维度对数据进行去中。
提交阶段及Checkpoint的制作完成