声明: 1. 本文为我的个人复习总结, 并非那种从零基础开始普及知识 内容详细全面, 言辞官方的文章
2. 由于是个人总结, 所以用最精简的话语来写文章
3. 若有错误不当之处, 请指出
状态一致性:
三个级别:
-
at-most-once
发生故障重启后, 数据会丢失; 即不做任何处理
-
at-least-once
发生故障重启后, 数据被重复计算(如重复sum); 使用ack应答机制支持重复提交
-
exactly-once
精准一次性, 不重不漏
需要开启检查点, 它才能有效
端到端一致性, 需要Source端, Flink内部, Sink端同时满足精准一致性, 木桶短板效应
exactly-once的保证:
Source端 exactly-once:
发生故障重启后, 保证不少消费数据: 可以指定Offset
进行重新设定消费位置, 即数据源支持重置偏移量
Sink端 exactly-once:
发生故障重启后, 保证不重复提交数据
三种方式:
-
幂等写入
外部系统支持幂等写入, 多次重复写入等效于第一次写入, 如ElasticSearch指定id
-
事务写入:
-
两阶段提交
满足原子性; 先预提交, 再正式提交
-
预写日志(WAL, Write Ahead Log)
目的: 加强数据可靠性 & 实现原子性
先把要提交的数据写到临时日志里:
- 若正常提交结束, 则将日志里的数据刷写到磁盘
- 若发生异常, 则不将日志里的数据刷写到磁盘
优点:
- 日志进行了持久化, 加强了数据的
可靠性
- 若不发生异常再落盘, 保证了事务的
原子性
-
Flink内部 exactly-once:
发生故障重启后, 保证不重复计算数据
依赖CheckPoint
Flink和Kafka对接, 实现exactly-once:
Source端:
可以重置偏移量, 避免漏消费
Sink端:
使用了两阶段提交, 避免重复提交
当所有Task的快照任务完成后, JobManager会向所有Task发通知告知此次CheckPoint完成, 然后便会触发第二阶段的正式提交
Flink内部:
使用了CheckPoint, 避免重复计算(如重复sum)
CheckPoint:
CheckPoint VS SavePoint:
CheckPoint是Flink自动生成的
SavePoint是手动生成的, 启动程序时要想接着上次的继续运行, 必须指定SavePoint文件的位置
CheckPoint是为了防止意外宕机的, 所以默认在任务正常取消(点击Cancel按钮) 或 在正常结束后就将CheckPoint进行删除
持久化备份方式:
- 暂停整个应用程序, 进行备份
- 不暂停整个应用程序, 采用
分布式快照
算法
检查点算法:
需要等某个数据被所有Task都计算完毕后, 才开始进行检查点备份
通过barrier分界线(是插入到流中的一种特殊数据)进行实现, 遇到barrier便触发检查点
-
barrier到来之前的数据更改, 会被包含在当前barrier所属的检查点中
-
barrier之后的数据更改, 会被包含在之后的检查点中
barrier对齐:
实现了exactly-once
barrier向下游传递, Task会等待所有输入分区的barrier到达, 才开始触发检查点
-
对于上游barrier已经到达的分区, 继续到达的数据会被缓存
缺点: 这个缓存可能太占用内存, 甚至引发背压机制, 降低上游发送数据的速度
-
对于上游barrier还未到达的分区, 数据会被处理
barrier不对齐:
实现了at-least-once, 故障恢复后数据可能被重复计算(如重复sum)
不需要缓冲区, 不会触发背压机制