現代の分散システムでは、トレードオフが重要です。パフォーマンス、信頼性、スケーラビリティ、一貫性は無料で得られるものではなく、常にどこかで代償を払うことになります。ここで CAP 定理が登場します。これは、分散設計における避けられない妥協を理解するための出発点です。
CAP 定理はなぜ正しいのでしょうか? 実際に何を説明するのでしょうか? そして最も重要なのは、それで十分なのでしょうか? この記事では、CAP 定理、その限界、直面した批判、そして PACELC などの新しいアイデアがどのように議論を前進させているかについて説明します。早速見ていきましょう。
CAP 定理の最初のバージョンは、 ACID と BASEの論争として始まりました。しかし、時間が経つにつれて進化し、正式な証明を得て、今日知られている CAP 定理になりました。
CAP 定理は、分散システムが同時に満たすことができる特性は 3 つのうち最大 2 つであると述べています。
この制限により、エンジニアはシステムの目標と分散環境の現実に応じて厳しいトレードオフを強いられます。
CAP における一貫性は、 ACID トランザクションにおける一貫性とは異なります。CAP 定理では、これは線形化可能性または強い一貫性を指します。つまり、どのノードがリクエストを処理するかに関係なく、分散システム内のすべてのノードが常に単一の最新のデータ ビューを提示する必要があります。つまり、どのノードにクエリを実行しても、すべての読み取り操作は最新の書き込みを反映します。
💡 一方、ACID における一貫性は、データベース スキーマで定義されたルールに従って、トランザクションがデータベースをある有効な状態から別の有効な状態に移行させることに重点を置いています。整合性制約 (外部キー、一意制約など) を適用し、クラッシュが発生してもデータベースが無効な状態にならないようにすることがより重要です。
CAP における可用性とは、ネットワークの分割に関係なく、障害のないすべてのノードが受信したすべての要求に対して応答を返す必要があることを意味します。つまり、正常なノードが要求を受け取った場合、その要求を処理して応答する必要があります。ただし、CAP は応答が常に「正しい」または最新であることを保証するものではなく、ノードがサイレントに障害を起こさないことを保証するだけです (たとえば、 AP システムでは、ノードは、可用性を確保するために、分割中に古いデータで応答する場合があります)。
💡 Eric Brewer (CAP の原作者) は当初、この特性を「ほぼすべてのクエリが応答を受け取る」ともう少し柔軟に説明していました。しかし、CAP の正式な証明では、可用性がさらに厳しくなり、「クエリを処理するノードが正常である限り、すべてのクエリが応答を受け取る」ことが求められました。
ただし、実際には、可用性は絶対的な保証ではありません。応答を待つ時間の長さなど、システム固有の制約によって決まることがよくあります。実際のシステムでは、CAP 自体は遅延を直接考慮していませんが、応答時間 (またはタイムアウト) はSLA (サービス レベル契約) の形成に重要な役割を果たします。詳細については、こちらのブログ投稿をご覧ください。
パーティション耐性は、ネットワーク障害を乗り切るためのものです。ネットワーク分割 (パーティション) によりノードが通信できない場合でも、システムは設計上の選択に応じて一貫性または可用性の保証を満たす必要があります。パーティションは、パケットのドロップ、タイムアウト、またはネットワーク分割によりノードが通信できない場合に発生します。
分散システムは、完璧なネットワークを備えたおとぎ話の世界に存在するわけではありません。パケットはドロップされ、タイムアウトが発生し、レイテンシの急増は避けられません。このため、分散システムではパーティション耐性は譲れないものです。パーティションは遅かれ早かれ発生するため、どんなに魅力的に思えてもそれを無視することを「選択」することはできません。
CAP では、パーティション耐性は、何も起こらなかったかのようにシステムが稼働し続けることを意味するわけではありません。パーティション発生時に、システムが可用性 (AP) と一貫性 (CP) のどちらを優先するかを決定する必要があることを意味します。パーティション耐性を無視すると、実質的に非分散型のモノリシック システムを構築することになります。
CAP を理解する最も簡単な方法は、ネットワーク パーティション(分散システムの 2 つの部分が相互に通信できない状況) について考えることです。このようなシナリオでは、システムは次の 3 つの結果に直面します。
したがって、分割中は、システムは3 つの特性 (C、A、または P) のうち 2 つしか満たすことができません。分割が解決されると (つまり、ノードが再び相互作用すると)、システムは 3 つの特性すべてを回復できますが、分割中はトレードオフは避けられません。
非同期システムの定理の結果として、一貫性、可用性、およびパーティション耐性の組み合わせは次の 3 つだけ可能になります。
このタイプのシステムはクエリに応答しますが、返されるデータは必ずしも最新ではない可能性があり、データの更新は遅くなりますが、「常に」利用可能です。このようなシステムの例としては、DNS、DynamoDB、Cassandra などがあります。
このタイプのシステムは常に最新のデータを返しますが、パーティション分割されている場合、システム内の一部またはすべてのノードが応答しない可能性があります。アトミック更新が行われますが、タイムアウトが発生する可能性があります。Google BigTable、MongoDB、HBase、Redis などの NoSQL データベースはすべてこのタイプのシステムです。
このタイプのシステムは、パーティションがない場合には常に最新のデータを返します。最後の制限のため、通常、このようなシステムは 1 台のマシン内でのみ使用されます。例としては、従来のリレーショナル データベースがあります。
実際には、CA は基本的にパーティションのないモノリスであるため、CP と AP のどちらかを選択します。大規模システムの場合、設計者は P を放棄できないため、C と A の間で難しい選択を迫られます。
CAでは、ノード障害はサービスが完全に利用できなくなることを意味します。しかし、独立したモノリスを複製して負荷を分散できるため、スケーラビリティが無効になることはありません。
CAP 定理は分散システムにおける基本的な概念ですが、限界がないわけではありません。トレードオフの考え方を明確に示しているにもかかわらず、CAP 定理は複雑な現実を過度に単純化し、誤解や誤った適用につながっていると批判されることがよくありました。
最も一般的な批判の 1 つは、CAP 定理のトレードオフ(一貫性 (C)と可用性 (A)の選択) は、ネットワーク分割 (P) が実際に発生した場合にのみ適用されるというものです。通常の操作では、ネットワークが安定していて分割が存在しない場合、一貫性と可用性の間に本質的なトレードオフはありません。
さらに、これらのトレードオフはシステム全体に共通するものではありません。同じ分散システム内でも、
このニュアンスは、CAP に関する高レベルの議論では失われることが多く、システムが全体的に「CP」または「AP」として過度に単純化された分類につながることになります。
もう 1 つの重要な批判は、レイテンシとパーティショニングは実際には深く関連しているにもかかわらず、CAP 定理ではレイテンシが考慮されていないことです。例:
実際の分散システムでは、パーティション分割や高レイテンシが発生すると、システムはタイムアウト期間内に、おそらく古い結果を返して可用性を優先するか、より長く待機して(応答しない可能性もある)一貫性を優先するかを決定する必要があります。CAP のバイナリ ビューでは、これらの決定の複雑さは捉えられません。
CAP 定理では、一貫性、可用性、および分断耐性は、2 つの特性、つまり、これらを備えているか備えていないかのどちらかであると説明されています。しかし、実際には、これら 3 つの特性はすべてスペクトル上に存在します。
このプロパティの連続的な性質により、CAP は現代の分散システムの複雑さをモデル化するには過度に単純化されています。
CAP は分散システムにおけるトレードオフの理解に革命をもたらしましたが、このテーマに関する最終的な結論ではありません。Daniel J. Abadi が説明した PACELC 定理は、分散システムの設計に対する代替アプローチと考えられています。これは CAP モデルに基づいていますが、一貫性、可用性、およびパーティション耐性に加えて、これらの概念の組み合わせ間のレイテンシと論理的排他性も含まれています。
PACELC は、分散システムに対して 2 つの異なる動作モードを導入します。
分散システムではパーティションは避けられませんが、通常の運用中に発生する問題に比べると稀です。現代の分散システムでは、特にグローバル規模のアプリケーションでは、ネットワーク パーティションよりもレイテンシの方がボトルネックになることがよくあります。PACELCは、パーティションなしでシステムが動作する場合のトレードオフに対処することで、この点に焦点を当てています。障害シナリオでの動作のみに焦点を当てる CAP とは異なり、PACELC は、レイテンシ (L)と一貫性 (C)のバランスをとるためにアーキテクトが毎日行う決定を重視しています。
PACELC は、会話をパーティションを超えて通常の操作にまで拡張することにより、分散システムの日常的なパフォーマンスが適切な重要性を持って扱われることを保証します。
CAP 定理の定式化はコミュニティにとって重要な出来事であり、分散システム設計への影響に関する研究では、分散システムの設計者はシステムを 2 つの特性に限定すべきではなく、それぞれの特定のケースで必要な保証を最大化するよう努めるべきであることが示されています。この目的のためには、システムをセグメントに分割し、各セグメントに独自の要件を持たせ、各セグメントの要件に基づいてシステムを設計するのが合理的です。
CAP 定理は、何十年にもわたって分散システムの考え方の礎となってきました。この定理は、一貫性、可用性、分断耐性の固有のトレードオフについて推論するためのフレームワークを提供しました。しかし、多くの点で、これは現実を単純化したものであって、二者択一を前提とし、レイテンシなどの重要な要素を無視しています。
PACELC は CAP を基盤として、次のことを認識しています。
CAP と PACELC はどちらも貴重なツールですが、どちらもシステムを構築するためのステップバイステップのレシピではありません。代わりに、トレードオフを評価し、分散アーキテクチャの限界を理解するためのメンタルモデルを提供します。
読んでいただきありがとうございます!
何か気になることや、共有したい考えはありますか? 以下にコメントを残してください。私のブログをチェックするか、 LinkedIn 、 Substack 、またはTelegramで私をフォローしてください。