このページの目次
実システムにおけるコンセンサスの実践
etcd、Consul、ZooKeeper——3つの実システムにおける共通のコンセンサス問題に対する3つのエンジニアリング的解決策。Raft+boltdb、Raft+Gossip、ZAB。コンセンサスプロトコルは中核だが全てではない。線形整合性読み取り、リース、watch メカニズム、メンバー管理にはそれぞれ独自のエンジニアリング上のトレードオフがある。
etcd
etcd は最も広く使用されている Raft 実装(Go)であり、Kubernetes の中核依存関係です。すべての K8s オブジェクト(Pods, Services, ConfigMaps)は etcd に保存されます。
アーキテクチャ
各ライトリクエストは以下のフローを経ます:Raft propose → commit → boltdb への apply → response。リードリクエストには2つのモードがあります:
- Serializable Read: ローカルの boltdb から直接読み取る(Raft を経由しない)→ 古いデータ(stale)を返す可能性がある
- Linearizable Read (デフォルト): ReadIndex メカニズムを使用。1) リーダーは現在の commitIndex を記録する; 2) 過半数のフォロワーにハートビートを送信し、自身がまだリーダーであることを確認する; 3) 状態機械が ≥ その commitIndex まで apply するのを待つ; 4) 読み取り。これにより、読み取りは置き換えられたリーダーのデータを参照しないことが保証されます。
Watch
etcd は long-poll watch をサポートしています:クライアントは key prefix を指定し、サーバーは変更イベントを返します。Kubernetes のコントローラーパターン(Informer)は etcd watch を基に実装されています。
Consul
Consul は、サービスカタログの整合性レプリケーションに Raft を使用し、メンバーの発見とヘルスチェックの伝播に Gossip (SWIM) を使用します。これにより、「整合性が必要なデータ」と「最終整合性でよいデータ」が分離されています。
設計原則:サービス登録(どのサービスが提供されているか)には強整合性が必要 → Raft。メンバーの死活判定(どのノードが生きているか)には最終整合性で十分 → Gossip。
ZooKeeper (ZAB プロトコル)
ZooKeeper の ZAB (ZooKeeper Atomic Broadcast) プロトコルは Raft より8年前に設計されており、設計目標が異なります:
- Raft: すべてのサーバーのログは完全に同一である
- ZAB: リーダーのログが権威であり、フォロワーはリーダーよりも多くのエントリを持っている可能性がある(ただし上書き可能)
ZAB の「順序保証」は、Raft のようなグローバルな線形整合性順序ではなく、FIFO クライアント順序です。つまり、クライアントからの複数のリクエストは送信順序が保持されますが、異なるクライアント間には順序保証がありません。
なぜ ZooKeeper はまだ存続しているか
ZooKeeper の先駆的な優位性と Java エコシステムにより、多くのレガシーシステムがそれに依存しています(Kafka の旧バージョン、Hadoop、HBase など)。しかし、新しいシステムでは etcd(よりシンプル、Go ネイティブ、K8s の依存関係)への傾斜が強まっています。
コンセンサスの適用シーン
コンセンサスは万能ではありません。それは「複数のノードが単一の値について合意する」問題を解決します:
コンセンサスを使うべき場面: コンセンサスを使うべきでない場面:
- リーダー選挙 - 大容量データのレプリケーション (gossip を使用)
- 分散ロック - リーダーベースではないレプリケーション
- 設定管理 - ヘルスチェック
- メタデータ管理 - ログ集約
大多数のシステムはコンセンサスを必要としていません。それらが求めているのは、最終整合性によるレプリケーション(Gossip, 非同期レプリケーション)または単一マスター + WAL(大多数の SQL DB のマスター-スレーブレプリケーション)です。
参考
- etcd: github.com/etcd-io/etcd, raft.github.io
- Consul: consul.io/docs/architecture
- ZooKeeper: "ZooKeeper: Wait-free coordination for Internet-scale systems" (2010)
Keywords: etcd, Raft, boltdb, Consul, Gossip, ZooKeeper, ZAB, linearizable read, ReadIndex