分散スナップショットとChandy-Lamportアルゴリズム
止められない分散システムの「全体の状態」を、処理を止めずに一貫した形で写し取れます。マーカー伝播でノードと通信路を矛盾なく捉える Chandy-Lamport の原理と、デバッグやチェックポイントへの応用がつかめます。
- 1.分散スナップショットは、各ノードのローカル状態と、それらをつなぐ通信路の途中にあるメッセージを、矛盾なく1枚に切り取る手法。
- 2.Chandy-Lamport はマーカーという特別なメッセージを流すだけで、システムを止めずに一貫したグローバル状態を記録する。FIFO 通信路を前提にする。
- 3.得られるのは「実際に起きた瞬間」ではなく到達可能な一貫状態だが、デッドロック検出やチェックポイント、終了検知にそのまま使える。
「全体の状態」を撮るのがなぜ難しいか
1台のプロセスなら、ある瞬間にメモリをダンプすればそれが状態です。ところが分散システムには全ノード共通の「今この瞬間」がありません。各サーバーの物理時計はずれており、状態を問い合わせるメッセージ自体が遅延します。ノード A の状態を聞いた直後に A が B へ送金メッセージを出し、その後で B の状態を聞けば、送金が「どこにも存在しない」スナップショットが出来上がります。逆順ならお金が二重に存在します。
ここで欲しいのは厳密な同時刻ではなく、一貫したグローバル状態 (consistent global snapshot) です。定義はこうです。あるイベント(メッセージ受信など)がスナップショットに含まれるなら、それより因果的に前のイベントもすべて含まれていること。送金の「受信」が記録されたのに「送信」が記録されていない、という因果の逆転を許さない切り口、と言い換えられます。
分散システムの全体状態は、各ノードのローカル状態(残高・変数など)だけでは足りません。送信済みだがまだ届いていない、通信路 (channel) を飛んでいる途中のメッセージも状態の一部です。これを取りこぼすと、合計残高が合わなくなります。Chandy-Lamport が「通信路の中身」まで律儀に記録するのはこのためです。
カット(cut)と一貫性
各ノードのイベント列に1点ずつ「ここまでを撮った」という線を引く——これをカットと呼びます。カットが一貫している (consistent cut) とは、カットの左側で受信されたメッセージは、その送信もカットの左側にあること。送信が右(カット後)なのに受信が左(カット前)にある、いわゆる「未来から来たメッセージ」を含むカットは不一貫です。
時間 →
P1: ──●send(m)──────────|cut1 送信はcut後 ─┐
P2: ──────────●recv(m)──|cut1 受信はcut前 ─┘ → 不一貫(因果逆転)
P1: ──●send(m)──|cut2 送信がcut前 ─┐
P2: ──────────●recv(m)|cut2 受信もcut前 ─┘ → 一貫
一貫したカットが捉える状態は、実際に起きたとは限らない点に注意します。並行(因果順序のない)なイベントの相対順序は入れ替え可能なので、撮れた状態は「実際の実行を、起きうる別の正しい実行に並べ替えたときに現れる状態」です。重要なのは、それでも到達可能で矛盾のない状態であり、安定述語の判定には十分だということです。
Chandy-Lamportアルゴリズム
K. Mani Chandy と Leslie Lamport が1985年に示したのが、システムを止めずに一貫したカットを得る手順です。前提は2つ——通信路は信頼でき(メッセージは欠落しない)、かつFIFO(送った順に届く)であること。鍵はマーカー (marker) という、通常のメッセージとは区別できる特別な印を流すことです。
開始ノードはまず自分のローカル状態を記録し、全出力通信路にマーカーを送出します。各ノードは次の規則だけに従います。
| 状況 | ノードの動作 |
|---|---|
| 初めてマーカーを受信(自分はまだ未記録) | 自分のローカル状態を即記録し、そのマーカーが来た通信路を「空」と記録。全出力路へマーカーを送る |
| 2回目以降のマーカーを受信(記録済み) | そのマーカーが来た通信路について、状態記録後〜マーカー到着前に届いた通常メッセージを通信路状態とする |
| マーカー受信前に届く通常メッセージ | 通常どおり処理しつつ、その通信路の通過メッセージとして記録に加える |
直感はこうです。マーカーは「この後ろに送ったものは新しい状態」という境界線として通信路を流れます。FIFO なので、ある通信路で「ローカル状態を記録した後・マーカーが来る前」に受け取った通常メッセージは、まさにカットを跨いで飛んでいた途中のメッセージです。これを通信路状態として捕まえれば、ノード状態+通信路状態の合計が辻褄の合う1枚になります。
マーカー処理(FIFO通信路を仮定)
on receive MARKER from channel c:
if 自ノード未記録:
record local state # 自分のスナップショット
record c as empty # cの途中メッセージは無し
send MARKER to all out channels
else:
record c の状態 =
「local記録後〜このMARKER到着前」にcで受けた通常メッセージ列
各ノードが「全入力通信路からマーカーを受け取った」時点で、そのノードの記録は完了です。全ノードが完了すれば、断片を集めてグローバルスナップショットが完成します。
FIFO 通信路の保証があるからこそ、「ローカル状態記録後に同じ通信路で届いた通常メッセージ=カットを跨いだ途中メッセージ」と一意に判定できます。もし追い越しが起きると、マーカーより後に送られたメッセージがマーカーより先に届き、カット後のメッセージをカット前の通信路状態に混ぜてしまいます。TCP のような順序保証付き通信路が前提になるのはこのためで、UDP 直叩きなどでは別途シーケンス番号で順序を回復する必要があります。
何が保証され、何が保証されないか
得られるカットが一貫していることは証明できます。直感的には、あるノードが状態を記録するのはマーカーを受けてからであり、マーカーは送信側の記録後に出されます。よって「受信が記録済み(カット前)なら、その送信も記録済み」が成り立ち、因果逆転が起きません。一方で前述のとおり、撮れた状態は実時刻の特定の瞬間と一致するとは限りません。
この性質が役立つのは安定述語 (stable predicate) の検出です。一度真になれば二度と偽に戻らない性質——たとえばデッドロックや計算の終了——は、一貫スナップショット上で真と判定されれば、実システムでも(その後)真です。逆に、刻々と変わる瞬間的な値(ある一瞬の総スループットなど)の厳密測定には向きません。
| 応用 | 撮ったスナップショットの使い方 |
|---|---|
| デッドロック検出 | 待ちグラフを一貫状態で再構成し、閉路の有無を調べる |
| 分散デバッグ | 全ノード+通信路の整合した断面を再現し、不変条件の破れを点検する |
| チェックポイント/復旧 | 一貫状態を保存し、障害時にそこから全ノードを巻き戻して再開する |
| 終了検知・GC | 「全プロセス停止かつ通信路が空」を安定述語として判定する |
ローカルなWAL/チェックポイントとの違い
単一ノードのWAL(先行書き込みログ)やチェックポイント機構は、1台の中の一貫性を扱います。Chandy-Lamport が解くのはそれらを横断した、ノード間にまたがる一貫性です。各ノードが勝手にローカルチェックポイントを取ると、復旧時に「受信は残るが送信は消えた」孤児メッセージや、復旧連鎖が際限なく巻き戻るドミノ効果が起こり得ます。協調的(coordinated)チェックポイントとして Chandy-Lamport 型のマーカーを使えば、全体が一斉に一貫した断面で固定され、これらを構造的に防げます。
時刻でなく因果順序で一貫性を組み立てる発想は、論理クロックの系譜と地続きです。マーカーの代わりにベクタークロックやハイブリッド論理クロック(HLC)とTrueTimeで「読みたい時点」を境界として与える手法もあり、いずれも「全ノード共通の今」が無い世界で一貫した断面をどう定義するか、という同じ問いに答えています。スナップショットを保存して障害から全体を再開する考え方は、分散合意(Paxos / Raft)でログを揃える発想とも補完的に働きます。
Chandy-Lamport は理論的に簡潔ですが、実装では各通信路にマーカーが1本ずつ流れる(完全結合なら N×(N−1) 本のオーダー)こと、参加ノードが動的に増減する場合の扱い、非 FIFO 経路での順序回復、スナップショット中も通常処理は止めないことによる記録漏れの防止が論点になります。Apache Flink のストリーム処理が採用する「分散スナップショット(バリア方式)」は本アルゴリズムを実用化したもので、マーカーに相当するバリアをデータストリームに挿入し、状態を非同期にチェックポイントします。原理を押さえておくと、こうした実システムの挙動が一気に読めます。
まとめ
分散スナップショットは、全ノード共通の「今」が無い世界で、ローカル状態と通信路を飛ぶ途中のメッセージを矛盾なく1枚に切り取る技術です。Chandy-Lamport はマーカーという境界線を FIFO 通信路に流すだけで、システムを止めずに一貫したカットを得ます。撮れるのは実時刻の瞬間ではなく到達可能な一貫状態ですが、デッドロック検出・分散デバッグ・協調チェックポイント・終了検知といった安定述語の判定にはこれで十分です。鍵はつねに、時刻ではなく因果順序で一貫性を定義することにあります。
データベース Article
分散スナップショットとChandy-Lamportアルゴリズムを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
分散システム
比較で見る軸
難易度: advanced / カテゴリ: データベース / タグ数: 5
導入後に効く点
Chandy-Lamport はマーカーという特別なメッセージを流すだけで、システムを止めずに一貫したグローバル状態を記録する。FIFO 通信路を前提にする。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- データベース
- タグ数
- 5
判断チェックリスト
- 自社の用途が「分散システム / スナップショット」に近いか確認する。
- 強みである「分散スナップショットは、各ノードのローカル状態と、それらをつなぐ通信路の途中にあるメッセージを、矛盾なく1枚に切り取る手法。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。