分布式快照捕获算法
2023-12-18 21:57:11 # 技术

前言

在许多情况下,知道分布式系统所处的全局状态是很有用的。分布式系统的全局状态(Global State)包括每个进程的本地状态和当前正在传输中的消息,所谓正在传输中的消息即该消息已经被发送但还没有被交付。

有很多原因表明,知道分布式系统的状态是很有用的。例如,当已知本地计算已经停止并且也没有消息在传输时,系统显然进入了一个不能继续前进的状态。此时,通过分析全局状态我们就能得知系统是进入了死锁还是分布式计算已经正确的结束了。

注:本文内容主要摘自「分布式系统原理与范型」,主要用于本人学习回顾。

关于全局状态和分布式快照

Chandy和Lamport在其1985年发表的论文Distributed Snapshots:Determining Global States of Distributed Systems 中提出了一个简单直接的记录分布式系统全局状态的方法,该方法引入了分布式快照(Distribute Snapshot)的概念。

分布式快照反映了该分布式系统可能处于的状态,且重要的是,该记录的状态是全局一致的。这意味着,如果快照已经记录了进程P收到了来自进程Q的一条信息,那么应该也记录了进程Q确实发送了这个消息。否则,快照将会记录一个已经被接受但从未被发送的消息。需要注意的是,相反的情况是可以接受的,也即快照可以记录一个已经被发送但还尚未被接受的消息。

全局状态的概念可以用一个被称为切口(cut)的示意图来表达。如下图所示,穿越进程P1、P2和P3时间轴的虚线表示的是一个一致的切口。该切口表示了「为每个进程记录的最后事件」,记录了事件$m_1$的发送和接受,以及事件$m_2$的发送。

IMG_6746735F12FC-1

作为对比,下图是一个不一致的切口,快照中记录了事件$m_1$的发送和接受,但是仅记录了事件$m_3$的接受而未记录其发送。

IMG_CC2C77FC7968-1

分布式快照捕获算法的描述

为了简化对分布式快照捕获算法的解释,我们假设分布式系统可用一个彼此通过单向点对点通信通道相连的进程集合来表示。例如,进程可能在任何进一步通信发生前首先建立TCP连接。

任何进程都可以启动该算法来捕获一个分布式快照。启动算法的进程P通过记录它自己的本地状态而启动。然后,它可以通过每个流出通道发送一个标记,表明接受者应该参与记录全局状态。

进程Q通过一个进入通道C接收到一个标记,该进程根据它是否已经保存了本地状态来决定下一步动作。

  • 如果进程Q尚未保存其本地状态,它就先记录本地状态,然后也通过它自己的每个流出通道发送一个标记。
  • 如果进程Q已经保存了其本地状态,则通道C上的标记表明Q应该记录该通道的状态。该状态是从进程Q上次记录了它自己的本地状态开始,到它接受了该标记为止,Q所接受到的消息序列组成。

当一个进程接受并处理了它的所有进入通道的标记时,就认为该进程已经完成了算法中与它有关的部分。此时可以将它记录的本地状态和它为每个进入通道记录的状态收集起来,发送给发起此快照的进程P。后者随后分析当前状态。需要注意的是,与此同时,分布式系统可以作为一个整体继续正常运行,也即分布式快照算法不会影响分布式系统的正常运行。

cut.drawio

还有一个需要注意的地方是,因为任何进程都能发起该算法,所以可能同时存在几个快照。为此,标记上附有发起该快照的进程的标识符(可能还有一个版本号)。只有在进程已经通过它的每个进入通道接收到了某个标记后,它才能完成与该标记相关的快照的创建。