分散システムにおけるノード管理とSWIMプロトコルの仕組み
はじめに
分散システムは大規模システムで採用されているスケーラブルで柔軟なアーキテクチャですが、その一方で「ノードが今も正常に動いているかどうか」を正確に把握することが難しいといった側面があります。本記事では、分散システムが抱える課題と、それに対する解決策の一つであるSWIMプロトコルについて解説します。
分散システムの課題
分散システムでは、複数のノード(コンピュータ)が連携して処理を行いますが、以下のような理想的な前提に依存すると、重大な問題が発生します。
- ネットワークは常に信頼できる
- レイテンシーは存在しない
- ノードは常に応答する
現実には、ネットワークの遅延、パケットロス、ノードクラッシュは避けられません。こうした前提のもとで構築されたシステムは、障害を誤検知したり、ノード間通信の失敗により、連鎖的な障害(カスケード障害)を引き起こすリスクがあります。
状態管理のための基本手法:PingとHeartbeat
分散システムでは、各ノードの状態を管理するために、以下のようなシンプルな方法がよく用いられます。
-
Ping方式
あるノードが他のノードに対して直接問い合わせ(ping)を行い、一定時間内に応答があるか確認します。
-
Heartbeat方式
各ノードが定期的に「自分は生きている」という信号(ハートビート)を他のノードに送信します。
これらの方法は基本的ですが、ネットワーク環境の不確実性により「応答がない=障害」と単純に判断することは危険です。
例えば、AからCに対して、直接的にpingを送信した場合、ネットワークの混雑やパケットロスにより返答(ACK)がない状況が発生します。この時、Cが生きていても故障として誤検知(偽陽性)されてしまいます。

SWIMプロトコルとは?
SWIM(Scalable Weakly-consistent Infection-style Process Group Membership)は、スケーラブルなフォールトディテクション(障害検出)とメンバーシップ管理を目的としたプロトコルです。
SWIMは基本的にPing形式を用いていますが、Pingが失敗した場合に備えて、他のノードに間接的なPingを依頼するという仕組みを持っています。
こうすることでネットワークの一時的な不安定性による誤検知を減らせたり、ピアツーピア型でスケーラブルな設計を実現することができます。

- 直接Ping
- ノードAがノードCに直接Pingを送る
- Cが正常であれば
ACKを返し、AはCが生きていると判断
- 応答がない場合:間接Ping(indirect ping)
- Aは一定時間
ACKを待っても応答がなければ - 他のノード(例:B, D)に「ping-req」を送信し、Cへ代わりにPingさせる
- 応答の代理確認
- B または D が C に直接 Ping を送り、Cから
ACKを受け取れたら - その
ACKを Aに転送(proxy ack)することで、Aは C が生きていると判断
- 間接Pingでも応答がない場合
- A は C を「suspect(疑わしい)」状態としてマークし始める
- 一定時間応答がないままなら、C を「dead(障害)」とみなす
- ゴシップによる情報の拡散
- A が「Cで障害」と判断した場合、その情報を他のノードに知らせる
-
Ping/Ping-Req/Ack メッセージに状態情報を添付
- 例:
dead(C)やsuspect(C)
- 例:
- この情報は他のノードにも伝播され、B, Dなども C で障害があることを徐々に認識
参考
Discussion