状态
flink中通过状态来实现容错、状态一致性以及checkpoint机制,
对于状态通俗来讲就是将数据或者程序运算的中间结果进行备份,这样可以保证程序中途出错可以从这里恢复;
状态类型
程序中保存的状态保存的具体类型是什么,哪些状态可以保存呢?
状态后端
状态后端指的是我们将要备份的数据存在那个地方,flink中有三个方式来保存状态,默认是保存在内存当中
-
内存中: memoryStateBackend
-
RockDBStateBackend,将状态存储在本地的RockDB数据库中,实际就是一种内存和磁盘的混合使用;
-
FsStateBackend,本地状态保存在taskmanager中,在使用checkpoint时候就是将其存入文件系统中
checkpoint
checkpoint保证了flink的可靠性,因为它也实现了数据的一致性,实际就是定期的程序各个执行状态进行保存,出错后可以实现恢复;
检查点工作机制
checkpoint的运行工作机制就是:
JobManager内部有一个协调器,在周期型的生成barrier,从最开始的数据源开始插入,随着数据流向后广播传递;
当这个barrier到了一个task时,相当于一个开关,开启当前task的备份;通常一个task中会对应上游多个task向他传递数据流,那这个task会等到所有的上游task到齐之后在触发备份机制,
当然这其中会涉及barrier对齐的特性,就是当某一个上游task中的barrier先到了,那么这个barrier之后的数据会等待,知道所有的上游task中所有的barrier都到齐以后开始checkpoint才开始计算,这样就可以保证数据的一致性,精准一次消费;
当这个task完成备份以后会向jobmanager里的协调器发一个消息,通知到这次保存的checkpoint的地址和相关的元数据;
当数据处理的最后完成checkpoint,在jobmanager收到后就会通知本次全局的checkpoint完成,同时它会备份之际的元数据;
当然在sink的时候会涉及二阶段提交(2pc),就是一开始先预提交,收到jobmanager的 完成通知,会进行正式提交,这样来保证精准一次消费;
checkpoint算法
chandy-lamport算法,异步分界线快照算法,这个算法可以实现不停止流的处理,同时进行checkpoint备份;
数据一致性
*数据一致性级别:*
at-most-once(最多一次)*😗
这其实是没有正确性保障的委婉说法——故障发生之后,计数结果可能丢失
at-least-once(至少一次):
这表示计数结果可能大于正确值,但绝不会小于正确值。也就是说,计数程序在发生故障后可能多算,但是绝不会少算;
exactly-once(严格一次):
这指的是系统保证在发生故障后得到的计数结果与正确值一致.既不多算也不少算
端到端一致性
source端
需要外部源可重设数据的读取位置.目前我们使用的Kafka Source具有这种特性: 读取数据的时候可以****指定offset****
flink内部
依赖checkpoint机制
sink端
需要保证从故障恢复时,数据不会重复写入外部系统. 有2种实现形式:
a) 幂等(Idempotent)写入
所谓幂等操作,是说一个操作,可以重复执行很多次,但只导致一次结果更改,也就是说,后面再重复执行就不起作用了。
b)事务性(Transactional)写入
所谓幂等操作,是说一个操作,可以重复执行很多次,但只导致一次结果更改,也就是说,后面再重复执行就不起作用了。
b)事务性(Transactional)写入
需要构建事务来写入外部系统,构建的事务对应着 checkpoint,等到 checkpoint 真正完成的时候,才把所有对应的结果写入 sink 系统中。对于事务性写入,具体又有两种实现方式:预写日志(WAL)和两阶段提交(2PC)