CAP定理の整理とAWSリソースの対応関係

# CAP定理とは

まずここでは理論的なCAP定理の説明をします。

CAP定理とは、

**分散システムにおいて、ネットワーク分断が発生した場合、「一貫性」、「可用性」、「分断耐性」の3つの特性のうち、同時に2つまでしか完全には満たすことができない**

というものです。

# CAP定理の3つの特性

CAP定理は以下の3つの特性からなります。

1. 一貫性
2. 可用性
3. 分断耐性

それぞれについて簡単に説明します。

## 一貫性(Consistency)

「一貫性」とは「すべてのノードで同じ最新のデータが取得できること」を指します。

クライアントが任意のノードにリクエストを送ったときに、常に最新のデータを返すことが保障されているというのが「一貫性」になります。

つまり、システムに更新が行われた場合、その結果がすべてのノードで即座に反映され、どのノードからも同じ結果を取得できることを意味します。

例えば、ネットワークが分断されているときに、最新ではないデータを返すとこれは「一貫性がない」状態になります。

## 可用性(Availability)

「可用性」とは「システムが常に応答し続け、リクエストに応答すること」を指します。

たとえシステムの一部が障害を起こしていたり、ネットワークに遅延が生じていても、「可用性」があるシステムではクライアントのリクエストに応答します。返される結果が最新かどうかに関わらず、何らかの応答を得ることができることを意味します。

例えば、「キャッシュ」という技術は可用性を高めるための効果的な施策だと言えます。最新であるかどうかはさておき、クライアントに返すべきものは準備できている状態だからです。

## 分断耐性(Partition Tolerance)

「分断耐性」とは「ネットワークの分断が起きてもシステムが動作し続けること」を指します。

分散システムは、多くの場合、複数のノードやネットワークにまたがって構成されています。そのため、ネットワークの一部が分断されてしまうことが起こり得ます。「分断耐性」とは、このようなネットワークの分断が発生しても、システムが動作し続けることを意味します。

# CAP定理の具体例

CAPの定理の「**3つの特性のうち、2つまでしか同時に満たすことができない**」というのが本当にそうなのか具体例を用いながら確認していきましょう。

想定シナリオ:

銀行のオンラインシステムを考えます。

## 1. 一貫性と可用性を選択

**説明**：ユーザーが常に正確な最新のデータを取得でき、システムは常に応答させます。

**分断耐性の欠如**：ネットワーク分断時に、データの一貫性を保つために、一部のノードへのアクセスを制限またはシステム全体を停止させる必要があります。これにより、システムはネットワーク分断に耐えられず、分断耐性が失われます。

## 2. 一貫性と分断耐性を選択

**説明**：ネットワーク分断時でもデータの一貫性を保ち、支店間で同期が取れるまでシステムを一時停止させます。

**可用性の欠如**：ネットワーク分断時、データの一貫性を保つために、ユーザーのリクエストに応答できない可能性があるため、可用性が失われます。つまり、ユーザーは一時的にシステムを利用できません。

## 3. 可用性と分断耐性を選択

**説明**：ネットワーク分断時でもシステムは動作し続け、ユーザーはリクエストに応答を得られます。

**一貫性の欠如**：ネットワーク分断時に、各ノードが独立してデータを処理するため、データの整合性が保証されず、ユーザーによって異なる結果が返される可能性があります。これにより一貫性が損なわれます。

# AWSサービスとCAP定理の関係

CAP定理について理論的な説明をしてきましたが、実は現実的に考えたときに私たちは理解を修正する必要があります。

分散システムでは分断耐性は必須の特性であり、これを犠牲にすることは現実的に困難です。

ネットワークの分断は避けられないため、分断耐性を前提として、一貫性と可用性のどちらかを選択していく必要があるのです。

- (分断耐性を意識しない(一貫性、可用性>分断耐性))
    - CA型
    - 現実では困難
- **同期が取れるまでシステムを停止させ、一貫性を優先する(分断耐性>一貫性>可用性)**
    - **CP型**
    - 強い一貫性の性質を持つ(Strong Consistency)
- **古い情報を返すことで、可用性を優先する(分断耐性>可用性>一貫性)**
    - **AP型**
    - 遅れるが最終的には一貫性を保とうとする(Eventual Consistency)

CP型とAP型のAWSにおいてどのサービスが該当するかを説明します。

## CP型

### Amazon RDS

- リレーショナルデータベースであり、強い一貫性を提供
- ネットワーク分断時には、データの整合性を保つためにフェイルオーバーが発生し、一時的に可用性が損なわれる可能性がある
- 具体例
    - 金融取引システム
        - トランザクションの正確性が求められるため、データの一貫性が非常に重要

### Amazon Aurora

- リレーショナルデータベース
- 強い一貫性を提供しつつ、高い可用性も実現していますが、ネットワーク分断時には可用性が一時的に損なわれる可能性がある
- 具体例
    - eコマースプラットフォーム
        - 大量のトランザクションを処理し、データの一貫性と可用性が重要

### Amazon DocumentDB

- オープンソースデータベース「MongoDB」と互換性を持つ、ドキュメント指向データベースサービス
- 具体例
    - リアルタイム分析システム
        - データの一貫性を保ちながら高速なクエリを実行する必要がある場合

### Amazon ElastiCache(Redis)

- オープンソースソフトウェア「Redis」を利用したキャッシュ向けデータベースサービス
- デフォルトではCP型として動作し、一貫性を重視しますが、設定により可用性を優先することも可能
- 具体例
    - ランキングシステム
        - ゲームやSNSでリアルタイムにランキングを更新・表示する必要がある場合

## AP型

### Amazon ElastiCache(Memcached)

- オープンソースソフトウェア「Memcached」を利用したキャッシュ向けデータベースサービス
- 具体例
    - Webページのキャッシュ
        - 高速なレスポンスが求められるが、多少のデータの古さが許容される場合

### Amazon DynamoDB

- スケーラブルな特性を持つスキーマレスNoSQLデータベースサービス
- 強い一貫性が必要な場合はオプションで設定可能
- 具体例
    - リアルタイムログ収集
        - 大量のデータを高速に書き込む必要があるシステム

### Keyspaces

- オープンソースデータベース「Apache Cassandra」を利用したマネージドNoSQLデータベースサービス
- 一貫性レベルをクエリごとに調整できるため、ユースケースに応じてバランスを取ることが可能
- 具体例
    - タイムシリーズデータの保存
        - センサーデータやログデータなど、高い書き込みスループットが必要な場合

2つに分けましたが、どのリソースも設定のチューニングにより、一貫性と可用性のバランスは調整することが可能です。

# まとめ

- CAP定理の理論的な意味は**広域な環境で分散してデータを保存する場合、「一貫性」、「可用性」、「分断耐性」の3つの特性のうち、2つまでしか同時に満たすことができない**というものであった
- しかし、現実的な意味合いは少し異なり、**分散システムでは分断耐性が前提条件であり、その上で一貫性と可用性のトレードオフを行う必要がある**
- AWSリソースには様々な状況に対応できるものが揃っており、設定のチューニングにより自分のサービスに適切なバランスを実現することができる