プロンプトとコンテキスト
あるサービスが注文、在庫、またはソーシャルコンテンツをリージョン間でレプリケーションしています。面接官は、なぜパーティションが発生すると一貫性と可用性の選択が生じるのか、そしてなぜ正常稼働時であっても一貫性とレイテンシーの選択が生じるのかを尋ねています。優れた回答とは、このモデルをユーザーへの約束、読み取り/書き込みパス、および測定可能なテストに関連付けるものです。
面接官が見極めているポイント
CAPの障害発生時の条件とPACELCの正常運用時の条件を区別できているか、正確な一貫性モデルを定義できているか、そしてリージョン間のラウンドトリップ、調整(coordination)、古いデータの読み取り(stale reads)、ビジネスリスクを結び付けられているかを見ています。単に4つの文字を暗記して答えたり、データベースに永続的なラベルを貼り付けたりするだけでは、設計として不完全です。
最初に確認すべき明確化のための質問
- linearizability、session consistency、またはbounded stalenessのどれが必要ですか?
- レイテンシーの目標はp95ですか、それともp99ですか?また、読み取りと書き込みのバジェットはどれくらいですか?
- どの注文操作がキューイングやリトライ可能で、どの操作が即座に失敗しなければなりませんか?
- レプリカはどのリージョンに配置されており、ユーザーのリクエストパス上にリージョン間のラウンドトリップが含まれていますか?
- 競合は自動的にマージされるべきですか、補償処理されるべきですか、それとも手動で確認されるべきですか?
30秒で答えるためのフレームワーク
PACELCは次のように読みます:パーティション(Partition)がある場合は可用性(Availability)と一貫性(Consistency)のどちらかを選択し、それ以外(Else)でパーティションがない場合はレイテンシー(Latency)と一貫性(Consistency)のどちらかを選択します。CAPはパーティション発生時の保証に焦点を当てていますが、PACELCは日常的なレプリケーションの調整コストを追加しています。私なら一貫性とレイテンシーのバジェットを定義し、注文操作ごとにクォーラム調整またはbounded-staleレプリカを選択した上で、パーティション、リージョン間レイテンシー、リカバリの訓練を行ってその約束を検証します。
ステップごとの詳細解説
ステップ 1: 4つの文字を展開する
Pはノード間の通信障害または許容できない遅延、Aはリクエストが契約の範囲内で応答を受信すること、Cはシステムが表明する一貫性の保証、Eはパーティションがない通常ケース、Lはより低い応答レイテンシーです。PACELCはレプリケーションシステムの設計のための分析フレームワークであり、新しいネットワークプロトコルではありません。
ステップ 2: まずパーティション分岐を処理する
東京とシンガポールが通信できない状況を想定してください。双方が反対の在庫削減を受け入れ、即座に成功させた場合、強一貫性を維持することはできません。片側のみに書き込みを許可するか、不確実なリクエストを拒否すると、可用性が一部犠牲になります。決済、在庫、一意性は通常一貫性を保護しますが、ソーシャルカウンターなどは一時的な古さ(staleness)を許容できます。
ステップ 3: 通常時のレイテンシー分岐を説明する
ネットワークが正常であっても、リージョン間の強一貫性読み取りはリモートの確認、クォーラム、またはコミットログを待つ可能性があり、ラウンドトリップレイテンシーが加算されます。ローカルレプリカはp99を低減しますが、古いバージョンを返す可能性があります。このトレードオフは日常的に存在します。CAPを「パーティション外では一貫性にコストがかからない」と述べているかのように説明すべきではありません。
ステップ 4: 製品ラベル単位ではなく、リクエスト単位で選択する
同じサービスであっても、在庫の書き込みは同期調整を経由し、製品詳細の読み取りはローカルレプリカにルーティングすることができます。同じデータであっても、テナントやエンドポイントごとに異なる読み取り保証を公開できます。製品全体をCPまたはAPと呼ぶのではなく、パスごとにバージョン、古さの境界(staleness bounds)、タイムアウトの挙動、リトライセマンティクスを文書化してください。
if partition:
protect_invariants_or_return_retryable_error()
else:
choose_remote_confirmation_or_bounded_staleness()ステップ 5: ビジネスコストを契約に変換する
注文は処理中として表示できますが、支払いを二重に請求してはなりません。レコメンデーションリストは数秒間古くても構いません。すべての操作には、べき等性キー(idempotency key)、バージョン条件、または競合イベントが必要です。低レイテンシーの読み取りがその古さのバジェットを超える場合は、明示的な状態を返すか、信頼できるプライマリレプリカを使用してください。
ステップ 6: オブザーバビリティシグナルを選択する
p50、p95、p99レイテンシー、古い読み取りの比率、バージョン遅延、調整タイムアウト、競合数、リトライ成功率、リカバリ時間を追跡します。リスクの低い読み取りによって在庫書き込みの失敗が隠蔽されないよう、操作タイプごとにメトリクスを分割します。
ステップ 7: 障害訓練でループを閉じる
単方向のネットワークロス、リージョン間遅延、メッセージの重複、部分的なリカバリを注入します。レスポンス、べき等性レコード、競合キュー、補償会計を確認します。リカバリ後は、ログの再生順序、バージョンの収束、ユーザーから見える状態を検証し、その結果を使用して一貫性とレイテンシーのバジェットを調整します。
優れた回答例
私はPACELCの両方の分岐を説明します。パーティション中は一貫性または利用可能な応答を保護し、通常運用中は一貫性または低レイテンシーを保護します。在庫削減にはべき等性キーを用いた同期調整を使用し、確認が取得できない場合はリトライ可能な状態を返します。製品の説明やレコメンデーションには、bounded-staleなローカル読み取りを許可します。各APIは一貫性モデル、p99目標、古さの境界を明記します。タイムアウト、バージョン遅延、競合を監視し、パーティションおよびリカバリの訓練を実行して、ユーザーに二重請求が発生したり不可能な在庫状態が表示されたりしないことを証明します。
よくある間違い
間違い:PACELCを4つの恒久的なカテゴリーとして扱う
PACELCはトレードオフを検討するためのレンズです。システムはエンドポイント、テナント、または障害フェーズごとにポリシーを変更できるため、各文字は永続的な製品特性ではありません。
間違い:Eはリカバリ後にのみ存在すると主張する
Eはネットワークパーティションのない通常の運用フェーズを意味します。リージョン間の確認、読み取り、コミットのすべてにおいて、一貫性対レイテンシーのコストが発生し得ます。
間違い:低レイテンシーと結果整合性を同一視する
低レイテンシーレプリカは、セッション保証や単調読み取り保証を提供する場合がありますし、境界のない古さを持つ場合もあります。1つの大雑把なラベルを使用するのではなく、バージョンの関係と古さの境界を明記してください。
間違い:ビジネス上の推論をデータベース名に置き換える
同じ製品でも、異なる読み取りおよび書き込みオプションを公開できます。不変条件、許容可能なユーザー状態、メトリクスから始め、プロトコルや設定がそれらをどのように満たすかを示してください。
フォローアップの質問と回答
フォローアップ:PACELCはCAPを無効にしますか?
いいえ。PACELCはCAPのパーティション分岐を維持しつつ、設計者に対して通常運用時にも一貫性とレイテンシーのトレードオフが存在することを再認識させます。
フォローアップ:リージョン間レイテンシーのコストを支払う価値があるのはどのような場合ですか?
追加されるp99と誤った結果によるコストを1つの決定表にまとめます。古さや競合が不可逆的な損失を引き起こす場合は、レイテンシーバジェットを一貫性に費やします。それ以外の場合はbounded stalenessと非同期修復を使用します。
フォローアップ:読み取りと書き込みで異なるポリシーを使用できますか?
はい。書き込みにはクォーラムまたは権限を持つリージョンからの確認を要求し、読み取りにはローカルレプリカ、セッション一貫性、または強一貫性を選択できます。API契約でその違いを公開する必要があります。
フォローアップ:ポリシーが機能していることを証明するメトリクスは何ですか?
パーセンタイルレイテンシー、古さの持続時間、バージョン遅延、競合および補償の成功率、パーティション拒否率、リカバリ時間を、クリティカルなビジネス操作ごとに分割して使用します。
フォローアップ:注文が成功した後に競合が発見された場合はどうなりますか?
べき等性キーと監査ログを使用して重複イベントを特定し、ビジネスルールに従って補償またはエスカレーションを行います。決済や在庫の競合は、last-write-winsによって隠蔽することはできません。