Chandy-Lamport快照算法仿真实现
分布式系统中存在的问题
在简单的非分布式环境中发现的问题,如互斥、饿死和死锁等,它们都有可能出现在分布式环境中。实际上,后一种环境下出现这些问题的可能性更大,因为它涉及到很多的实体,它们会引起混乱。没有全局状态更是增加了其中的麻烦。
操作系统或参与的进程不可能知道所有进程的整个状态。它只能知道自己的状态(也就是本地进程)。为了获取远程进程的相关信息,它要获取来自其他进程的消息,或者和其他进程进行通信。
使用快照记录状态
在一个分布式计算系统中,为了保证数据的一致性需要对数据进行一致性快照。
由于进程是可能崩溃的,我们需要保证在进程崩溃重启后,系统仍然能够正常运行,或者说我们要从某个检查点恢复程序的运行状态,这时就需要将系统在某个时间点的状态保存起来。也就是说我们需要对分布式系统进行一次快照存储,保存每个节点在当时的状态以及每个消息队列在当时的状态。
简单来说就是用来在缺乏类似全局时钟或者全局时钟不可靠的分布式系统中来确定一种全局状态。
Chandy-Lamport快照算法
在 Chandy-Lamport 算法中,为了定义分布式系统的全局状态,我们先将分布式系统简化成有限个进程和进程之间的 channel 组成,也就是一个有向图:节点是进程,边是 channel。因为是分布式系统,也就是说,这些进程是运行在不同的物理机器上的。那么一个分布式系统的全局状态就是有进程的状态和 channel 中的 message 组成,这个也是分布式快照算法需要记录的 。
因为是有向图,所以每个进程对应着两类 channel: input channel, output channel。同时假设 Channel 是一个容量无限大的 FIFO 队列,收到的 message 都是有序且无重复的。Chandy-Lamport 分布式快照算法通过记录每个进程的 local state 和它的 input channel 中有序的 message,我们可以认为这是一个局部快照。那么全局快照就可以通过将所有的进程的局部快照合并起来得到。
快照的建立过程
主要包括一下三个部分:
- Initiating a snapshot: 也就是开始创建 snapshot,可以由系统中的任意一个进程发起
- Propagating a snapshot: 系统中其他进程开始逐个创建 snapshot 的过程
- Terminating a snapshot: 算法结束条件: 所有的进程都收到 marker 信息并且记录下自己的状态和 channel 的状态(包含的 message)
具体实现过程:
•进程 P i
–计算局部状态
–发送一个标志到 chan ij 和 chan ik
–分别对来自 chan ji 和 chan ki 的消息进行计数
•进程 P j 若从 chan ij 收到标志
–计算局部状态并记录 chan ij 的状态为空
–**发送标志到 ** chan ji 和 chan jk
–对来 chan kj 的消息进行计数
•进程 P k 若从 chan ik 收到标志
–计算局部状态并记录 chan ik 的状态为空
–发送标志到 chan ki 和 chan kj
–对来 chan jk 的消息进行计数
程序设计框架
描述:
在i,j,k三个节点构成的模拟网络环境中基于全联通逻辑拓扑结构,以资源转移为应用背景,仿真实现Chandy和Lamport快照算法。每条通道均有不同的延迟,且任何通道内均允许存在多条消息。
节点功能:
- 接收来自控制节点的原始操作消息,完成对应的资源转移、发起快照操作,如果是结束消息,则在完成所有操作后结束程序的运行
- 接收来自其他P节点的资源转移和快照标记消息,完成相应的操作
要求:
- 模拟通道延时 sleep()
- 端口
- 通信要求:使用write/read语句和使用短连接支持交互
- 数据类型:字符串
- 格式
- 日志调试
设计:
- 输入:
- 输出:
- 静态参数
- 程序结构:线程设定
- 数据结构:快照301#302#的数据结构
- 流程