mcpField
C
consistency-coordination

consistency-coordination

github.com/proyecto26開発113314 回インストール1 日前に更新
リポジトリ

consistency-coordination について

レプリケーションやシャーディングを使うシステムの保証を選ぶエンジニア向けに、一貫性と調整を設計するスキルです。一貫性モデル、合意方式、サービス間トランザクション、キー配置を比較できます。

主な機能

  1. 01一貫性モデルの選択
  2. 02リーダー、クォーラム、合意方式の比較
  3. 03Sagaと分散トランザクションの指針
  4. 04一貫性ハッシュによるキー配置
  5. 05ネットワーク分断とフェイルオーバーの分析

活用シーン

  1. 01レプリケートデータの読み取り保証の選択
  2. 02ネットワーク分断時の動作設計
  3. 03リーダー選出の調整方式の選択
  4. 04弾力的なノード群へのキー分散

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/proyecto26/system-design-skills --skill consistency-coordination

インストール後、Claude Code で/consistency-coordinationを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
deep-dive.md
references/providers/
aws.md
gcp.md
generic.md

詳細

翻訳後に原文が更新されています。最新の内容は原文をご確認ください。

一貫性と調整

データが複数のノードにあるとき、読み手にどのような保証を提供するのか、そして独立したノードがどのように単一の答えに合意するのかを決めます。ここを誤ると、古いデータや競合するデータが気づかれないまま配信されるか、ネットワーク接続が切れた瞬間にシステムが停止します。これは分散システムで最もよく起こり、最も深刻な障害です。

これを使う場面

状態をノード間で複製、シャーディング、または調整する場合はいつでも使います。たとえば、レプリケーション方式やクォーラム方式の選択、一貫性レベルの選択、リーダーの選出、拡張可能なフリートへのキーの分散(コンシステントハッシュ)、または複数のサービスにまたがる変更のコミットなどです。「書き込み直後の読み取りには何が見えるのか?」「パーティション発生中はどうなるのか?」という質問が出たら、すぐに検討してください。

使わない場面

レプリカのない単一ノードでは調整するものがありません。クォーラムやコンセンサスを持ち込まないでください(YAGNI)。多くのアプリでは数秒の古さは許容できます。結果整合性で十分なのに強い一貫性や分散トランザクションを選ぶと、要件で求められていない保証のためにレイテンシと運用上の負担が増えます。不変条件を満たす最も安価なモデルを選びましょう。正しさの要件に迫られる前からRaftや2PCの名前を出すのは危険信号です。

まず確認すること

  • 読み取りが古いと、何が壊れますか? 残高の誤りと、「いいね」数が少し古いことでは、必要なシステムが異なります。(→ requirements-scoping。)
  • ユーザーは自分の書き込みをすぐに見られる必要がありますか? 書き込み後の読み取り保証は、グローバルな強い一貫性よりはるかに安価です。
  • パーティションやリージョン喪失の影響範囲はどの程度ですか? CAP/PACELCの選択を左右します。(GUIDEの障害モード#1。)
  • 書き込み競合と競合の形 — キーごとに単一の書き込み元ですか、それとも競合解決が必要な同時書き込み元がありますか?
  • レイテンシ予算 — 同期調整には往復通信(リージョンをまたぐ場合もあります)が加わります。予算内に収まることを確認してください。(→ back-of-the-envelope。)

選択肢

一貫性モデルを選ぶ(読み取りが得る保証):

  • 強い一貫性/線形化可能 — すべての読み取りで、最新のコミット済み書き込みが見えます。不変条件をグローバルに保つ必要がある場合(残高、在庫、一意性)に使います。
  • 書き込み後の読み取り/単調性 — セッション内では自分の書き込みが見え、後戻りしません。プロフィールの編集や、「投稿して、自分の投稿を見る」といった用途に使います。
  • 因果的一貫性 — 読み取りで原因→結果の順序を守ります(返信が親より先に表示されることはありません)。コメント、チャット、共同編集に使います。
  • 結果整合性 — レプリカは「いずれ」収束しますが、読み取りには遅れが生じることがあります。「いいね」数、フィード、キャッシュなど、古さの影響が小さい用途に使います。

複製されたデータの合意方法を選ぶ:

  • シングルリーダー(プライマリ) — 1つのノードがすべての書き込み順序を決め、フォロワーに複製します。明確な書き込み元を許容できる場合に使います。一般的なデフォルトです。
  • クォーラム(R + W > N) — 過半数に対して読み取り/書き込みを行います。ワークロードに合わせてRとWを調整します。調整可能な一貫性と可用性を必要とするリーダーレスストアに使います。
  • コンセンサス(Raft/Paxos) — 障害発生時も含め、過半数が複製ログに合意します。リーダー選出、設定、メタデータ、ロックなどのコントロールプレーンに使います。

複数のキー/サービスにまたがる変更を調整する:

  • Saga — 補償用の取り消し処理を伴うローカルトランザクションの連続です。グローバルロックが不可能なサービス間で使います。結果整合性を受け入れる方式です。
  • 2PC/分散トランザクション — コーディネーターを介し、ノード間で全か無かの原子性を実現します。原子性が必須で、そのコストを受け入れられる場合にのみ使います。

ノード間でキーを分散する — コンシステントハッシュ(このスキルの担当範囲):キーとノードをハッシュリングに配置し、キーを時計回りで次のノードに割り当てます。ノードを追加または削除しても、再割り当てされるのはキーの約K/N個だけです。通常のhash(key) % Nではほぼすべてのキーが再割り当てされるため、これにより再割り当ての嵐を避けられます。仮想ノードを使うと負荷が均等になり、ホットスポットも抑えられます。キャッシュ、リーダーレスストア、ロードバランサーのバックエンドで標準的なパーティショニング方式です。仕組みについてはreferences/deep-dive.mdを参照してください。

トレードオフ

選択肢解決すること悪化すること変更するタイミング
強整合性/線形化可能性正確性、古い読み取りの防止レイテンシ(ラウンドトリップ/クォーラム)、パーティション発生時に利用不可(CP)古いデータが許容されるようになったら → read-your-writes/結果整合性に緩和
read-your-writesグローバルなコストをかけずに「自分の変更を確認」ほかのユーザーには古いデータが表示される。セッション/スティッキールーティングが必要グローバルな不変条件が生じたら → 強整合性に移行
結果整合性最も高い可用性と最も低いレイテンシ(AP)古い読み取りや競合する読み取りが発生する。競合解決が必要不変条件が不一致を許容できなくなったら → より強いモデルに移行
シングルリーダー順序付けがシンプル。書き込み競合がないリーダーが書き込みの単一障害点になる。フェイルオーバーの空白期間がある。フォロワーからの読み取りには遅延がある書き込みスループットが1ノードの限界を超える、またはリーダーのリージョンが失われたら → マルチリーダー/クォーラムに移行
クォーラム(R+W>N)呼び出しごとに整合性と可用性を調整可能読み取りと書き込みのコストが高い。並行書き込みには依然として競合処理が必要クォーラムの遅い経路さえもコストがかかりすぎる場合 → リーダーまたはローカル読み取りに移行
コンセンサス(Raft/Paxos)ノード障害に耐える合意過半数が必要(クォーラム未満では可用性が失われる)。書き込みレイテンシ。複雑大規模化したデータプレーンで必要になったら → 調整をサービスに移す
Sagaグローバルロックなしでサービスをまたぐ変更分離性がない。部分的な状態が見える。補償処理の設計が必要真の原子性が必要な場合 → 2PC(コストを受け入れる)
2PC複数ノードにまたがる原子的なコミットコーディネーターが単一障害点になる。投票中にロックを保持する。障害時にブロックする厳密な原子性より可用性/スループットが重要な場合 → Saga

ストレス下での動作

このブロックの主な目的は障害時、つまりネットワークまたはノードが故障したときに何が起きるかを説明することです(GUIDE #1, #6)。

  • ネットワークパーティションは、CAPにおけるCとAの選択を迫ります。CP/強整合性システムは、不変条件を保護するため、少数派側での書き込みを拒否します。つまり、正確性のために可用性を犠牲にします。AP/結果整合性システムは、どこでも書き込みを受け入れ、後で調整します。つまり、可用性のために正確性を犠牲にします。どちらを選んだのか、その理由を明示してください。両方を維持する第三の選択肢はありません。
  • リーダーの喪失は選挙を引き起こします。その間、書き込みは一時停止するか(シングルリーダー)、リスクを伴いながら続行します(古いリーダーに書き込みを続けさせる場合 → スプリットブレインと履歴の不一致が発生)。フェンシングトークンと過半数のクォーラムにより、リーダーが2つ存在するのを防ぎます。
  • クォーラムが過半数を下回る(停止中のノードが多すぎる)場合、厳密なクォーラムストアは設計上、書き込みの受け入れを停止します。N − Wを超える数のノードが停止すると書き込みがブロックされ、N − Rを超えると読み取りがブロックされます。
  • 調整は障害の影響を増幅させます。 2PCコーディネーターがクラッシュすると、参加者はロックを保持したままになり、ブロックが発生します。クォーラムを失ったコンセンサスクラスターはコントロールプレーンを停止させ、それに依存するすべてのものを停止させます。リーダー選挙のタイムアウトを短くしすぎると、選挙ストーム(負荷が高い状況で選挙が繰り返されること)が発生する可能性があります。
  • 監視対象: レプリケーションラグ(古いデータが許容される時間)、リーダー選挙の頻度と所要時間、クォーラムの健全性(到達可能なノード数とNの比較)、競合/修復の頻度、そしてコンシステントハッシュの場合はノードごとのキー分布とリバランス量です。

フェイルオーバーのトレードオフ(アクティブ/パッシブとアクティブ/アクティブ、データ損失が起こりうる期間)についてはresilience-failureで説明しています。このブロックでは、それぞれの整合性に伴うコストを示します。

適用方法

  1. 不変条件を明確にします。 古い読み取りや競合する読み取りで何が破綻するのか、ユーザーが自分の書き込みを確認できる必要があるのか、パーティション障害の影響範囲はどこまでかを特定します(「まず明確化するための質問」を使ってください)。不変条件がなければ、デフォルトで結果整合性を選び、そこで止めます。
  2. トレードオフ表からモデルと合意形成方式を選びます。 データが許容できる最も弱い不変条件に保証を合わせ、書き込みを誰が管理するのか、ノード障害時に何を存続させる必要があるのかに応じて、シングルリーダー/クォーラム/コンセンサスを選びます。変更がサービス間にまたがり、原子性が必須の場合に限り、Saga または 2PC を追加します。
  3. パラメーターを設定します。 データストア単位ではなく、操作ごとに整合性レベルを設定し、重複が必要な場合は N、R、W を R + W > N となるように設定します。競合解決ポリシー(LWW/バージョンベクトル/アプリケーション側のリゾルバー)を選び、クラスター構成が変動する場合はキー配置にコンシステントハッシュを採用します。
  4. 選択をストレステストします。 CAP に関する方針を明示します。パーティション発生時、リーダー喪失時、クォーラム未達時にどうなるかを示します。スプリットブレインが防止され、協調処理によって障害がクラスター全体の停止に拡大しないことを確認します。
  5. 数値で規模を見積もります。 調整に必要なラウンドトリップのコスト(同一データセンター内とリージョン間)をレイテンシ予算と照らし合わせ、障害目標に応じて N の規模を決めます。これには back-of-the-envelope を使います。強整合性が予算を超える場合は、モデルを緩和します。
  6. プロバイダーに対応付けます。 デフォルトでは汎用的な手順を使います。クラウドが指定されている場合は、そのプロバイダーのファイルを参照し、マネージドサービスの整合性設定とクォーラムストアの制限を確認します。

すべきこと、すべきでないこと

すべきこと

  • 保証はデータストアではなく、操作ごとに設定します。ほとんどの読み取りは結果整合性とし、不変条件に関わる操作だけを強整合性にすることで、正確性のために必要な場合だけ調整コストを支払います。
  • CAP に関する方針を明確に示します。パーティション発生時に、どちらの側が書き込みを拒否するのか(CP)、または受け付けて後で調整するのか(AP)を明示します。両方を維持する選択肢はありません。
  • 重複と障害目標を考慮して R、W、N の規模を決め、過半数のクォーラムとフェンシングトークンでリーダーをフェンシングします。
  • バージョン(またはベクトルクロック)を返し、呼び出し側が競合を検出して解決できるようにします。

すべきでないこと

  • 不変条件によって必要になる前に、強整合性、コンセンサス、または 2PC を選ばないでください。古さはたいてい許容でき、グローバルな調整はレイテンシと負担を増やします。
  • 厳しい書き込み予算のもとで、リージョン間の同期強整合性や 2PC を実行しないでください。リージョン間のラウンドトリップは 100 ms 以上かかることがあります。
  • 選挙の合間に古いリーダーが書き込みを続けられる状態にしないでください。これはスプリットブレインです。
  • キーのシャーディングに hash(key) % N を使わないでください。メンバー構成の変更時に、約 K/N ではなく、ほぼすべてのキーが再配置されます。

重要な数値

調整コストを左右するのは CPU ではなく、ラウンドトリップです。同一データセンター内のラウンドトリップは 1 ミリ秒未満ですが、リージョン間では数十~約 100 ms 以上かかります。そのため、リージョン間の同期強整合性や 2PC では、書き込みごとに 100 ms 以上が加わることがあります。クォーラムのサイズは ⌊N/2⌋ + 1 です。N=3 の場合、2 ノードの合意が必要なため、クラスターは 1 件の障害に耐えられます。コンシステントハッシュでは、メンバー構成の変更時に再配置されるキーは約 K/N 個にとどまります(モジュロ方式ではほぼすべてです)。レイテンシ表と back-of-the-envelope の可用性のナイン計算を使ってラウンドトリップのコストを見積もり、障害目標に応じた N の規模を決めてください。

インターフェースの概要

契約は、操作ごとに明示する保証と、それを実現するパラメーターです。

ConsistencyLevel: STRONG | READ_YOUR_WRITES | CAUSAL | EVENTUAL
Quorum:           N (replicas), W (write acks), R (read acks)  // R + W > N ⇒ overlap
Write API:        write(key, value, level=STRONG) -> {version|vector_clock}
Read API:         read(key, level=EVENTUAL)       -> {value, version, stale?: bool}
Conflict policy:  last-write-wins(ts) | version-vector-merge | app-resolver

データストアではなく、操作ごとにレベルを設定します。ほとんどの読み取りは結果整合性でよく、不変条件に関わる一部だけに強整合性が必要です。バージョンを返し、呼び出し側が競合を検出して解決できるようにします。

プロバイダーの選択

デフォルトでは、上記の汎用的な手順を使います。ユーザーがクラウドを指定した場合は、マネージドサービスへの対応付け、クォータ/制限、プロバイダー固有のトレードオフについて references/providers/<provider>.md を参照します。そのプロバイダーのファイルが存在しない場合は、汎用的な手順を回答とします。

図

リーダー/フォロワー/パーティション分断のシナリオ、クォーラム読み取り/書き込み、またはコンシステントハッシュリングを可視化するには、プラグイン内の architecture-diagram スキルを使用してください。簡単な検討には、インラインのスケッチ(client → leader → [replication stream] → followers。パーティション分断は破線または途切れた矢印で表します)で十分です。Mermaid は埋め込まないでください。

関連する構成要素

  • data-storage — これと組み合わせます。レプリケーションとシャーディング/パーティショニング(仕組み)を担い、このブロックはそれらが実現する整合性保証を提供します。
  • messaging-streaming — データプレーンでの調整に対する代替手段です。メッセージの順序付けと厳密に一度の配信は、トランスポートレイヤーにおける同じ問題です。イベントの順序付けや重複排除が必要な場合に組み合わせてください。
  • resilience-failure — これにつながります。フェイルオーバー、再試行、グレースフルデグラデーションを担い、このブロックはそれが提供する可用性の仕組みに伴う整合性コストを見積もります。
  • caching — 分散キャッシュのシャーディングにはコンシステントハッシュ(このブロックが所有する概念)に依存し、鮮度と速度のトレードオフを扱います。
  • back-of-the-envelope — レイテンシーテーブルと、ラウンドトリップのコスト見積もりや N の規模決定に使う可用性ナインの計算は、ここが所有する概念です。
  • service-decomposition — サービス間の整合性(サガ/2PC)と、サービスディスカバリーを支える調整(リーダー選出、etcd/Consul/ZooKeeper など)において、これに依存します。
  • system-design — 設計で状態をレプリケーションまたは調整する際に、ここへ誘導するオーケストレーターです。

参考資料

  • references/deep-dive.md — CAP と PACELC の詳しい比較、整合性モデルの仕組み、クォーラムの計算、Raft/Paxos の概要、リーダー選出とスプリットブレイン(フェンシング)、コンシステントハッシュリングと仮想ノード、2PC とサガの内部動作を解説します。調整レイヤーを詳しく設計する際に読んでください。
  • references/providers/{generic,aws,gcp}.md — 調整サービス(ZooKeeper/etcd/Consul)、クォーラムストア、環境ごとのマネージドな整合性設定(例:Spanner の外部整合性、DynamoDB の整合読み取りフラグ)について解説します。

コメント