前言
Flink documentation 中 “work with state” 中提到了Flink的状态管理机制。实现思想来源于Chandy-Lamport的分布式快照算法。分别对理论和源码了解后,发现Flink其实是算法的一个极简实现。具体来说一下怎么来简化实现的。
Chandy-Lamport 分布式快照算法熟肉版
文章中通过Token传递的两个典型场景来分析分布式快照应该遵循的法则:
- Sender Record状态时,已发送的数量和Channel Record时已经接受数量一致;
- Receiver Record状态时,已经接受的数量和Channel Record时已经发送的数量一致;
关于模型本身不多说,适用于典型的数据有向传输场景。基于以上的规则,C-L给出了解决办法:
- Sender record状态前,发送一个Marker;
- Receiver 除了record自己的状态,还record Channel的状态,cause Channel没有实体承载计算逻辑。 具体细分两种场景:
- 收到marker时,还没有record,则记录channel为空,触发receiver record;
- 收到marker时,已经record过了,则记录channel的状态为从Record后到marker的所有记录,本质上是补充了一份record时刻Channel的状态;
论文本身后面都是在证明结果时有效的,不赘述,赶紧结合Flink来看看。
Flink的简化实现
首先Flink肯定保留了marker的思想,具体对应于Flink中的barrier。其次,我们可以从C-L算法中可以figure out Receiver是可以自主触发record的,Flink中各Operator是不能自主触发Record的。这是关键。看带来的效果:
- 在非主动触发的情况下,我们可以不用记录Channel的状态,按照C-L的算法,Channel中必然是空的。
- Operator到底需要记录什么?这个答案开始明确,需要记录的是Operator中持有的State,如果不带State完,其实啥都不需要记录。
- Source的State略有不同。因为Source更关注的是整流Restart后从哪个点读取数据,例如记录kafka的offset。
Flink State数据持久化
First of all,区分两个概念:State和 StateBackend:
- State,表示我们记录的状态数据&#x