Flink的基石 : Chandy Lamport Algorithm

Flink处理“流”,对流消息的处理支持三种级别语义分别是“At Most once、At Least once、Exactly once”。


At Most onces:消息最多被处理一次,sender发出消息之后,receiver无论是否处理成功,都不会再重发。类似于UDP协议的效果,只管发送,不管结果。


At Least once:消息至少被处理一次,sender发出消息之后,receiver处理失败或者处理成功但是回复sender确认成功的时候超时,都会重发,直到sender确认成功。这里消息就很有可能被多次重复处理,比如超时回复、消息发送之后断网之后又重连。类似于TCP协议效果,发送之后会确保receiver接收到,但是如果receiver出现异常,消息可能被处理2次,然后导致幂等问题。


Exactly once:消息恰巧被处理一次。不管出现任何异常整套系统对这个消息只处理一次。类似于TCP协议的效果再加上幂等。


看完以上对语义的解释,这些处理语义在分布式系统的实现难度正好逐渐增加。解决掉复杂度最高的处理语义,其他的在此基础上稍微简化些就能达到。在Flink中实现语义“Exactly once”,采用的是checkpoint,使用的是Asynchronous barrier snapshots 算法,而该算法是根据Chandy Lamport Algorithm进行了一些轻微的变种。所以Chandy Lamport Algorithm算法是Flink实现语义“Exactly once”的基石,该算法受之无愧。



首先如上图中所示,Chandy 与Lamport 发布这篇paper的题目“分布式快照:确定分布式系统的全局状态”,Chandy Lamport Algorithm 算法是一个采用分布式快照算法来解决记录分布式全局状态一致的算法。


普及一下什么是快照算法。


在维基百科中这样解释:“快照算法是一个用来在分布式同创建快照来是分布式系统的状态保持一致的算法,因为分布式系统中没有一个全局共享的内存和全局时钟,所以它基本是不可能的”。


Chandy Lamport Algorithm 的基本实现流程


在论文中把分布式系统简化为两个进程(process)上进行的论证


进程 p 与进程q,它们之间数据的交互通过socket channel  c 与 c’。p 发送消息通过 c 到达q,q发送消息通过c’到达p。


在然后作者采用的“single-token conservation”的模型,在此模型中进程中只有一个token。当进程拥有token状态记为sl,进程未拥有token状态记为s0。



在这些基础概念解释之后,请先看看下图,大概理解一下这幅图。



(1)首先进程p和q启动,token  in p [ p:s1 q:s0 ]


(2)p发送token去q进程,此时正在socket channel 中 传输,token in channel [ p:s0 q:s0 ]


(3)q收到token ,token  in q[ p:s0 q:s1] 


(4)这个时候q ack回复p,token in channel [ p:s0 q:s0 ] 


(5)p 收到回复 token  in p  [ p:s1 q:s0 ] 


通过上面的流程,在任意时刻都可以记录下俩进程中token的状态,此时再推广到多个进程,多个token基本都是一样。


伪代码:


这里解释一下,代码中的maker和token 可以理解为一个东西,就是一种消息类型,根据这种消息类型判读是否开启快照。


//(1)(2)

begin 

         p  records its state;

end    

then 

        p sends one marker along c after p records its state and before p sends further messagesalong c.     

//(3)(4) 

if q has not recorded its state then 

      begin 

                 q records its state; 

                 q records the state c as the empty sequence 

      end 

else 

       q records the state of c as the sequence of messages received along c after q’s statewas recorded and before q received the marker along c.


这个算法的核心,就是创造出一个maker来记录整个分布式链的状态,当链上的节点出现异常需要恢复的时候就根据当前状态找到之前的maker,然后重新计算,保证分布式状态一致。


好了,算法已经讲完,你是否有兴趣去看看原文呢。


下一篇博文将介绍Flink基于此算法的改进


欢迎关注公众号 “技术求索之路”

回复“基石1”获取

你可能感兴趣的:(Flink的基石 : Chandy Lamport Algorithm)