クラウドやマイクロサービスの普及により、複数のサーバーやデータベースノードを連携させて巨大なトラフィックを処理する「分散システム」が一般的になりました。
しかし、複数のマシンにデータを分散させて管理する際には、システムの設計者が必ず直面する根本的なトレードオフが存在します。それが CAP定理(CAP theorem / ブリューワの定理) です。
「どんな障害が起きても止まらず(可用性)、どのサーバーを見ても常に最新データが揃っていて(一貫性)、通信が途切れても壊れない(分断耐性)完璧なデータベース」を作りたいと誰もが考えます。しかし、CAP定理によれば 「分散システムにおいて、一貫性・可用性・分断耐性の3つを同時に100%満たすことは理論的に不可能」 であることが証明されています。
この記事では、CAP定理の基礎知識から、なぜ3要素を同時に満たせないのかの直感的な理由、現実のシステムにおける「CP」と「AP」の選定基準、ACID特性やBASE特性との違い、さらに実務で役立つ「PACELC定理」までを初心者にもわかりやすく図解を交えて解説します。
CAP定理の基本:3つの要素(C・A・P)とは?
CAP定理は、2000年に計算機科学者のエリック・ブリューワ(Eric Brewer)氏が提唱し、2002年にセス・ギルバート(Seth Gilbert)氏とナンシー・リンチ(Nancy Lynch)氏によって数学的に証明された分散システムの基本原則です。
CAP定理の名称は、分散システムが持つ以下の 3つの特性 の頭文字に由来しています。
| 特性 | 英語表記 | 定義・保証内容 |
|---|---|---|
| 一貫性 | Consistency(C) | 分散システム上の操作が単一コピーに対して実行されたかのように振る舞い、完了済みの最新書き込みと矛盾する古い値を返さない保証(線形化可能性)。 |
| 可用性 | Availability(A) | 障害を起こしていない稼働中のノードが受け取ったリクエストに対し、必ず正常な応答(最新である必要はない)を返す保証。 |
| 分断耐性 | Partition Tolerance(P) | ネットワークの切断やメッセージの遅延・損失によりノード間の通信が途絶(ネットワーク分断)しても、システムが所定の保証を維持できる性質。 |
単一コピーのように最新状態を保証"] A["可用性(Availability)
障害していないノードが必ず応答"] P["分断耐性(Partition Tolerance)
通信分断時も所定の保証を維持"] end C --- A A --- P P --- C
それぞれの特性が具体的に何を意味しているのかを掘り下げて確認しましょう。
一貫性(Consistency):単一コピーのように最新状態を保証
CAP定理における 一貫性(Consistency) とは、分散システム上のデータ操作が、あたかも単一のデータコピーに対して実行されたかのように振る舞うことを指します。具体的には、 線形化可能性(Linearizability) を保証し、完了済みの書き込みより古い値を後続の読み取りで返さないことが求められます。
もしあるクライアントがノードAのユーザー残高を「1,000円から2,000円」に更新して書き込みが正常に完了した後、別のクライアントがノードBを読み取った場合、ノードBも「2,000円」を返さなければなりません。古い値である「1,000円」を返すことは許されず、最新データを保証できない場合には読み取り要求に対してエラーを返すことも C の保証と両立します。
[!NOTE] データベースのトランザクションでおなじみの ACID特性 にも「C(Consistency / 整合性)」がありますが、CAP定理の一貫性とは意味が異なります。ACIDのCは「一意性制約や外部キー制約などのデータベースのルールを満たしているか」を意味します。一方、CAP定理のCは「分散システム上のデータ操作が、実時間順序に沿って単一コピーのように最新状態を返せるか(線形化可能性)」を意味します。
可用性(Availability):障害していないノードが必ず正常応答する
可用性(Availability) とは、 「障害していないノードが受け取ったリクエストに対して、必ず正常な応答を返すことを保証する性質」 です。
ここで重要なのは、応答が必ずしも最新のデータを含んでいる必要はないという点です。たとえ古いデータであっても、正常な応答として返されれば可用性の要件を満たします。なお、CAP定理の形式的な定義では、障害していないすべてのノードが受け取ったリクエストに対して有限時間内に応答を完了させることが要求されます。単に HTTPHTTP [エイチティーティーピー]HyperText Transfer Protocol。Webでのデータ転送プロトコル 500 のようなエラーを返せば可用性を満たす、という意味ではありません。
分断耐性(Partition Tolerance):通信障害下でも所定の保証を維持する
分断耐性(Partition Tolerance) とは、 「ネットワーク障害によってノード間の通信が途絶したり、メッセージが遅延・喪失したりする状況でも、システムが所定の保証を維持できる性質」 です。
物理サーバー間のLANLAN [ラン]Local Area Network。家庭やオフィスなど限られた範囲のネットワークケーブル抜け、ルーターの故障、クラウド事業者内のアベイラビリティゾーン(AZ)間通信の障害など、複数のマシンをネットワーク経由でつなぐ環境では、通信の分断を完全にゼロにすることは不可能です。ただし、分断耐性があるからといって、分断されたすべてのノードが必ず読み書きを継続できるわけではありません。分断時に一貫性と可用性のどちらを優先するかによって、各ノードの動作は変わります。
なぜ「3つすべて」を同時に満たせないのか?具体例で理解する
CAP定理の結論は、 「一貫性(C)・可用性(A)・分断耐性(P)の3つを同時に100%満たすシステムは存在しない。ネットワーク分断が発生したとき、CとAを同時には保証できない」 というものです。
なぜ3つ同時には満たせないのでしょうか。2台のサーバー(ノードAとノードB)でデータを複製しているシンプルな分散データベースを例に考えてみましょう。
※ 実際のCP型システムの動作は、リーダーの配置やクォーラムの状態によって異なります。この図はあくまで基本的な動作例です。
シナリオ:ネットワーク分断(P)が発生している状態での書き込み
- ノードAとノードBの間でネットワーク分断(Partition)が発生し、相互に通信できなくなりました。
- クライアント1が ノードA にアクセスし、残高を「1,000円」から「2,000円」へ更新しようとします。
- このとき、システムはネットワーク分断中に書き込みをどう扱うか、そして後から ノードB に「現在の残高はいくらですか?」と問い合わせたクライアント2へどう応答するかについて、 2つの設計方針 に分かれます。
選択肢1:一貫性(C)を優先する場合(CPの選択)
CP型のシステムでは、必要なノードとの合意を得られない場合、不整合を防ぐために ノードA側での書き込み自体を拒否(エラーまたは応答の保留) することがあります。また、仮に一方が過半数に属さず最新データを保証できない状態であれば、 ノードB側への読み取りも拒否 して古い値(1,000円)を返さないようにします。
- 結果: どのクライアントも古い不整合なデータを受け取らずに済み、データの 一貫性(C) は保たれました。
- 代償: 障害していないノードへの書き込みや読み取りリクエストを拒否したため、 可用性(A) が犠牲になりました。
選択肢2:可用性(A)を優先する場合(APの選択)
AP型のシステムでは、ノード間の通信ができない状態でも各ノードが応答を継続するため、ノードAは書き込みを受け付けて成功を返します。その後、更新情報をまだ受け取れていないノードBにクライアント2が照会すると、ノードBは手元にある古いデータ(1,000円)を正常応答として返します。
- 結果: クライアント1もクライアント2もエラーにならず応答を得られたため、 可用性(A) は保たれました。
- 代償: クライアント1の書き込み成功(2,000円)の後に「1,000円」が返されたため、 一貫性(C) が損なわれました。
結論:分断が起きたら「CかAか」のトレードオフになる
このように、ネットワーク分断(P)が発生した状態では、システムは 「一貫性(C)を守るために可用性(A)を諦めて書き込みや読み取りを拒否する」 か、 「可用性(A)を守るために一貫性(C)を諦めて古い可能性のあるデータを返す」 かのどちらか一方しか保証できません。
これが、CAPの3つを同時には満たせない理由です。
なぜ現実の分散システムでは「CA」を選べないのか?
CAP定理を初めて学ぶ際、「それなら P(分断耐性)を捨てて、C(一貫性)と A(可用性)の両立を目指す『CAシステム』を作ればよいのでは?」という疑問を持つ方が多くいます。
しかし、現代の分散システム設計において 「CA」という選択肢は実質的に存在しません 。
ネットワーク分断の対象外だが
単一障害点(SPOF)となる"] Q -->|Yes| Dist["分散環境(複数のマシン)"] Dist --> P_Must["ネットワーク分断(P)は物理的に不可避!"] P_Must --> Choice{"分断発生時にどちらを優先するか?"} Choice -->|一貫性を優先| CP["CP型システム
エラーにしてでも不整合を防ぐ"] Choice -->|可用性を優先| AP["AP型システム
古いデータの返却を許して応答を返す"]
ネットワークは必ず壊れる(Pは選択ではなく前提条件)
複数のサーバーをケーブルやスイッチ、Wi-Fi、クラウドの仮想ネットワークで接続している以上、ネットワークの遅延や一時的な切断を 100% 防ぐ魔法のインフラは存在しません。
ネットワーク分断を考慮しない設計では、通信障害が発生した際に、一貫性や可用性を維持できなくなる可能性があります。そのため、分散システムではネットワーク分断が発生することを前提に、障害時の動作を設計する必要があります。
したがって、現実の分散アーキテクチャにおける真の問いは「CAPのどれを2つ選ぶか」ではなく、 「ネットワーク分断(P)が起きた際に、一貫性(C)と可用性(A)のどちらを優先するか(CPかAPか)」 という二者択一になります。
[!IMPORTANT] 単一マシン上で動作するスタンドアロンのデータベース(単一構成の MySQLMySQL [マイエスキューエル]オープンソースのリレーショナルデータベース / PostgreSQLPostgreSQL [ポストグレスキューエル]高機能オープンソースのリレーショナルデータベース や組み込み型の SQLiteSQLite [エスキューライト]組み込み型の軽量SQLデータベース など)は、ノード間のネットワーク分断を考慮する必要がないため、一般的な説明では「CA」的な構成として扱われることがあります。ただし、これらは厳密には分散システムではないため、CAP定理の分類をそのまま適用する対象ではありません。マシン自体が故障すればサービス全体が停止するため、複数ノードで構成される分散システムとは障害に対する前提が異なります。
CP型 vs AP型:代表的なデータベースとシステムの比較
実際のソフトウェアやミドルウェアは、用途や業務要件に応じて「CP」または「AP」の設計思想を採用しています。
以下は各データベースの代表的な設計思想や標準的な構成に基づく分類です。実際のCAP特性は、レプリケーション方式、読み書きの整合性レベル、クォーラム設定、障害時の動作などによって変化するため、製品名だけでCP型・AP型を固定的に決められるわけではありません。
| 分類 | 設計思想 | 主な特徴・挙動 | 代表的なプロダクト・技術 |
|---|---|---|---|
| CP型 | 一貫性 + 分断耐性 | ノード間の分断が発生した場合、不整合を防ぐために一部ノードの書き込みや読み取りをブロック・エラーにする場合がある。 | etcd, ApacheApache [アパッチ]世界中で広く利用されているオープンソースのWebサーバーソフトウェア ZooKeeperZooKeeper [ズーキーパー]大規模な分散システムにおいて、設定管理や同期などを一元化する調整サービス, Consul(設定による), MongoDBMongoDB [モンゴディービー]ドキュメント型NoSQLデータベース(構成・設定による), HBase, CockroachDB |
| AP型 | 可用性 + 分断耐性 | ノード間の分断が発生しても、可用性を優先してリクエストへの応答を継続する。構成によっては各ノードが独立して読み書きを受け付け、後からデータの同期や競合解決を行う。 | Apache CassandraCassandra [カサンドラ]Apache開発の分散型NoSQLデータベース(デフォルト / 設定による), Apache CouchDB(構成・方式による), Amazon Dynamo(2007年原論文の設計) |
| CA型 | 一貫性 + 可用性 | ネットワーク分断が発生しないことを前提としたモデル。ただし、単一ノードのデータベースは厳密には分散システムではないため、CAP定理の分類をそのまま適用する対象ではない。 | (分散システムではないため厳密な対象外) |
[!NOTE] 上記の分類は代表的な設計思想に基づく傾向です。たとえば Apache Cassandra は標準では AP 寄りですが Consistency Level(クォーラム設定等)によって一貫性と可用性のバランスを調整でき、 MongoDB も Read Concern・Write Concern やレプリカセットの状態(例:セカンダリからの読み取りなど)によって保証内容が変わります。
なお、AWSAWS [エーダブリュエス]Amazon Web Services。Amazonのクラウドサービス の Amazon DynamoDBDynamoDB [ダイナモディービー]AWSのフルマネージドNoSQLデータベース は、2007年に発表された Dynamo 論文に由来する名称ですが、同論文の設計と現在の DynamoDB の内部実装は区別する必要があります。DynamoDB では、通常のテーブルやローカルセカンダリインデックス(LSI)に対して、デフォルトの結果整合性読み取りと、
ConsistentRead=trueを指定する強整合性読み取りを選択できます(グローバルセカンダリインデックスやストリームでは強い整合性の読み取りはサポートされません)。また、Global Tables では、リージョン間で非同期複製を行う Multi-Region Eventual Consistency(MREC)と、同期複製によって強い整合性を実現する Multi-Region Strong Consistency(MRSC)の2つのモードが提供されています。なお、MREC の Global Tables では、ConsistentRead=trueを指定しても、他リージョンで行われた直近の書き込みが反映されているとは限りません。リージョンをまたいだ強い整合性が必要な場合は、MRSC を選択する必要があります。
CP寄りの設計が選ばれやすいユースケース
データの不整合が致命的な問題になりやすい場面では、業務要件に応じて CP 寄りの設計が選ばれる傾向があります。
- 金融・決済システム: 銀行口座の残高引き落としや二重決済の防止など、金額の不整合を許容できない業務。
- ECサイトの在庫管理: 限定商品の在庫数がマイナスになってしまうオーバーセルを防止したい業務。
- 分散合意・クラスタ管理: KubernetesKubernetes [クーバネティス / クベルネテス]コンテナオーケストレーションシステムのクラスタ状態を管理する
etcdや、設定情報を一元管理する ZooKeeper。リーダー選出やロック管理で不整合が起きるとクラスタ全体が破綻するため、強固な一貫性が求められます。
AP寄りの設計が採用されることが多いユースケース
わずかなデータのズレよりも、システム全体が止まらずに応答し続けることが優先される場面では、AP 寄りの設計が採用されることが多くあります。
- SNSのタイムライン・いいね機能: 友人が投稿したメッセージや「いいね」の反映が数秒遅れても、サービス全体がエラー画面になるよりはるかに好まれます。
- IoTIoT [アイオーティー]Internet of Things。様々なモノがインターネットに接続される仕組みセンサーデータの収集・アクセスログ: 秒間数万件のログデータを欠損なく受け取り続けることが最優先のシステム。
- ショッピングカートの保持: AmazonのDynamo論文で有名な通り、「カートに商品を追加する操作でエラーを出してお客を逃すくらいなら、後でマージして重複を解消すればよい」という思想です。
ACID特性とBASE特性(結果整合性)の関係
分散システムを設計する上では、トランザクションの信頼性を保証する ACID特性 と、高い可用性や柔軟性を重視する BASE特性 の考え方もよく比較されます。
ACID特性:トランザクションの整合性と信頼性
伝統的なリレーショナルデータベース(RDBMS)は、トランザクションの信頼性を担保するために ACID特性(原子性・一貫性・分離性・耐久性)を重視します。
ACID特性はトランザクションの信頼性を保証するための性質であり、CAP定理のCP型・AP型とは直接対応するものではありません(ACIDのCはデータベースの制約・整合性ルールを指し、CAPのCは線形化可能性を指します)。ただし、分散データベースで強い整合性を維持するために、同期レプリケーションや合意形成を利用する構成では、CAP定理の観点から CP 寄りの設計になることがあります。
BASE特性:可用性と柔軟性を重視する考え方
一方、NoSQLNoSQL [ノーエスキューエル]Not Only SQL。関係データベース以外の様々なデータ管理システムの総称を中心とする分散データストアの文脈では、厳格な即時整合性よりも可用性や拡張性を優先するアプローチとして BASE特性 という考え方が提唱されました。
- Basically Available(基本的可用性): システムの一部ノードに障害が起きても、システム全体としてはリクエストに応答し続ける。
- Soft-state(柔軟な状態): 外部から新しい入力がなくても、ノード間のデータ同期やキャッシュの更新などによって、システムの状態が時間とともに変化すること。
- Eventual consistency(結果整合性): 新たな更新が行われず、レプリケーションなどの同期処理が正常に進めば、最終的に各ノードのデータが同じ状態に収束すること。
なお、ACIDとBASEは必ずしも完全な二者択一ではありません。実際の分散システムでは、重要なデータ更新には ACID トランザクションを使用し、サービス間のデータ連携には結果整合性を採用するなど、両方の考え方を組み合わせることがあります。
マイクロサービスアーキテクチャ(モノリスとマイクロサービス)などでは、サービスごとに独立したデータベースを持つ構成が一般的です。複数のサービスにまたがるデータ更新では、分散トランザクションによる厳密な同期を避け、結果整合性を前提とした設計を採用する場合があります。その際に利用される代表的な設計パターンが、複数のローカルトランザクションと補償処理を組み合わせる Saga パターンです。
実務で役立つ発展形:PACELC定理とは?
CAP定理は「ネットワーク分断という異常時」におけるトレードオフを論じたものでした。しかし、現実の運用では 「ネットワーク障害など起きていない通常時のパフォーマンス」 も極めて重要です。
この疑問に答えるために、2012年にダニエル・アバディ(Daniel Abadi)氏によって提唱されたのが PACELC定理(パセルク定理) です。
PACELC定理は、以下のように文章を分解して読み解きます。
【分断時(if Partition: P)】 → 可用性(Availability: A)をとるか、一貫性(Consistency: C)をとるか【それ以外の平常時(Else: E)】 → レイテンシ(Latency: L)をとるか、一貫性(Consistency: C)をとるかなぜ平常時にもトレードオフが生じるのか?
平常時(ネットワーク分断が発生していないとき)であっても、データの強い一貫性を保証するためには、リーダーや複数のレプリカとの通信、クォーラムによる合意形成などが必要になる場合があります。こうした通信や処理の完了を待つことで、レスポンス時間(レイテンシ: L)が増加する可能性があります。
一方、書き込みを受け付けたノードが他のノードへの複製完了を待たずに応答する設計では、レイテンシを抑えられる反面、直後の読み取りで古いデータが返される可能性があります。
代表的なDBのPACELC分類
以下は、Daniel Abadi 氏の2012年の論文で示された代表的な分類です。
- PC/EC型(例: Bigtable, HBase): 分断時は一貫性(PC)を優先し、平常時もレイテンシより一貫性(EC)を優先する。
- PA/EL型(例: Apache Cassandra, Amazon Dynamo原論文): 分断時は可用性(PA)を優先し、平常時も一貫性より低遅延(EL)を優先する。
- PC/EL型(例: Yahoo! PNUTS): 分断時は一貫性(PC)を優先し、平常時は一貫性より低遅延(EL)を優先する。
- PA/EC型(例: 2012年の論文で扱われたMongoDB): 分断時は可用性(PA)を優先し、平常時は低遅延より一貫性(EC)を優先する。
なお、CockroachDB などの比較的新しい分散SQLSQL [エスキューエル / シークエル]Structured Query Language。関係データベース(RDB)の管理や操作を行うデータベース言語データベースも、強い整合性と合意形成を重視する設計であり、PC/EC型に近い特性を持ちます(ただし、これは2012年の論文に記載された分類ではなく、現在の製品設計に基づく評価です)。また、上記はいずれも2012年当時の代表的なデータベース設計を基にした歴史的な分類であり、現在の製品のすべての動作を保証するものではありません。実際のシステムでは、バージョンやレプリケーション方式、整合性レベル、読み書きの設定(MongoDB の Write/Read Concern や DynamoDB の ConsistentRead、Cassandra の Quorum 設定など)によって特性が変わるため、個別の構成を確認する必要があります。
まとめ:CAP定理をシステム設計に活かすポイント
CAP定理は、分散システムにおいて「何かを100%得ようとすれば、別の何かを妥協しなければならない」という根本的な制約を教えてくれます。
最後に、CAP定理の要点を振り返りましょう。
- CAPの3要素: 一貫性(Consistency)、可用性(Availability)、分断耐性(Partition Tolerance)。
- 同時達成は不可能: ネットワーク分断が発生した場合、一貫性(C)と可用性(A)を同時に保証することはできない。
- 現実的な選択肢は CP または AP: ネットワーク分断(P)は物理的に不可避なため、「分断時に一貫性を守るか(CP)、可用性を守るか(AP)」の選択となる。
- ACIDとBASEの使い分け: 分散システムでは、データの重要度や業務要件に応じて、強い整合性を重視する設計と、結果整合性を許容して可用性を重視する設計を使い分ける。
- 平常時のトレードオフ(PACELC): 障害時だけでなく、平常時も「低遅延(L)か一貫性(C)か」のバランスを意識する。
システムを設計・選定する際は、「どちらの技術が優れているか」という二元論ではなく、 「対象となる業務ドメインやユーザーが求めているのは、厳格なデータ整合性なのか、それとも高い可用性や低遅延な応答なのか」 を見極めることが最も重要です。
以上で本記事の解説を終わります。
よいITライフを!
人気記事
- 1
- 2
- 3
- 4
- 5
思考の整理というテーマを、実務ですぐに使える具体的な「技術」として落とし込んだ一冊です。