检查点 就是某个时间点下的所有算子的状态快照。这个时间点就是等所有任务将“同一个数据”处理完毕的时候。
状态后端:是一个管理状态的组件,还负责将本地状态(检查点)持久化到远程文件存储系统中。
分类:
(1) 基于内存的hashmap状态后端。性能高,但是有内存资源耗尽的风险
(2) 基于rocksdb持久化存储的状态后端。适用于状态大,窗口长的情况下,因为会序列化和反序列化,访问状态的性能会差点。
我们用就是rocksdb状态后端。
jobManager的堆(heap)内存中
文件系统
具体实现接口:
(1) 大状态持久化保FileSystemCheckpointStorage:
(2) 性能考虑jobManagerCheckpintStorage
同时向数据流中插入一种特殊数据: 分界线,当遇到keyby这种分区算子,保存状态同时,会将分界线以广播形式分发给下游并行的算子;如果遇到sum这种,会接收上游多个分区的分界线数据,会进行分界线对齐(详细来讲:Sum算子接收两个不同的子任务的数据,收到了第一子任务的分界线数据,但是没收到第二个子任务的分界线数据,这时候如果第二个子任务传来正常的数据需要正常处理的,但是如果是第一个分界线已经到达的子任务再来数据,就需要等待写入缓存,只有第二子任务的分界线数据到达,然后状态保存,再做处理。
),现在版本的flink已经支持不对齐的检查点,会降低反压时候的checkpoint的执行时间,不过需要保存分界线来之前的数据,所以会增大单个checkpoint的大小。
精准一次性保证,就是不会重复消费数据,也不会丢失数据。Flink 是通过检查点保证的。
幂等写入(无论执行多少次,最终结果都一样),如果写入redis 这种键值对存储,数据重复写入,对结果不影响。还有写入mysql 按主键更新数据。
还有就是事务写入,将事务与检查点绑定在一起,通过检查点是否成功来提交或者回滚事务。具体来说就是,对不同的外部存储系统,有两种实现方式: