Geo-distributed / NewSQL の本質 ─ TrueTime・Raft・地理分散
ここまでの DB は、整合性 vs スケーラビリティのトレードオフで「どちらかを選ぶ」という建付けだった。RDB は単一ノード(または read replica)で強整合性、NoSQL は分散で eventual。
だが「地理を超えた強整合性」を実現する DB がある。Spanner(Google)と CockroachDB。これらが NewSQL と呼ばれる第 3 の系譜。
CAP 定理を超える話
分散システムは、Consistency / Availability / Partition tolerance の 3 つを同時には満たせない。P が必須なら、C と A のどちらかを諦める。
この定理は依然有効だが、現代では**「P が起きない時間帯では C も A も提供する」**という解釈が一般的。Spanner / CockroachDB は CP を選ぶ(P 時には A を諦める)が、P が起きていない通常時はほぼ完全に動くように設計されている。
これを実現する技術が、TrueTime(Spanner)と Raft + HLC(CockroachDB)。
Spanner の TrueTime
TrueTime:GPS 受信機と原子時計を組み合わせた、Google データセンター内のグローバル同期時計
graph TB
subgraph "DC 1(東京)"
GPS1[GPS 受信機]
AC1[原子時計]
GPS1 --> Master1[Time Master]
AC1 --> Master1
end
subgraph "DC 2(バージニア)"
GPS2[GPS 受信機]
AC2[原子時計]
GPS2 --> Master2[Time Master]
AC2 --> Master2
end
subgraph "DC 3(ロンドン)"
GPS3[GPS 受信機]
AC3[原子時計]
GPS3 --> Master3[Time Master]
AC3 --> Master3
end
Master1 --> S1[Spanner Server]
Master2 --> S2[Spanner Server]
Master3 --> S3[Spanner Server]
style Master1 fill:#e1f5ff
style Master2 fill:#e1f5ff
style Master3 fill:#e1f5ff
TrueTime の API
// 概念的な API
TT.now() = TTinterval { earliest, latest }
// earliest <= 真の現在時刻 <= latest
// 不確実性の幅は通常 1-7 ms
TrueTime は “現在時刻” を返さない。“現在時刻が含まれる範囲” を返す。これが核心。
Commit Wait
書き込みは:
- 全 replica で書き込み
t = TT.now().latestを commit timestamp とするTT.now().earliest > tになるまで待つ(commit wait)- その後にクライアントに ACK
つまり「自分の commit の latest 時刻を、世界の earliest 時刻が超える」まで待つ。これで 後の任意のトランザクションが、自分より前の時刻で commit されることがない ことを保証する。
これが External Consistency(外部整合性)= Linearizability の地理分散版。
コスト
- 書き込みレイテンシ:commit wait の分(1-7ms)+ 全 replica への書き込み(数十 ms)
- インフラ:GPS / 原子時計が必要(Google 以外には自前で持てない)
- AWS / Azure には Spanner 互換のものはない(GPS / 原子時計の問題)
CockroachDB の代替アプローチ:HLC + Raft
CockroachDB の設計 は「原子時計なしで Spanner 並みの整合性を実現する」のが目標。
Hybrid Logical Clock (HLC)
HLC = (physical time, logical counter)
- Physical time: NTP 同期(精度数 ms)
- Logical counter: メッセージ伝搬で単調増加
物理時計のずれを logical counter で吸収する。物理時計のドリフトが許容範囲(通常数百 ms)に収まる限り、因果順序が正しく保たれる。
Raft Consensus
データを Range という単位(数十 MB)に分け、各 Range は複数ノードで Raft で複製:
graph TB
subgraph "Range A: leader"
L[Leader]
end
subgraph "Range A: followers"
F1[Follower 1]
F2[Follower 2]
end
Client[Client] --> L
L --> F1
L --> F2
Note1[書き込みは majority の ACK で commit]
style L fill:#e1f5ff
書き込みは Leader を経由して majority(過半数) の Follower に複製されてから ACK を返す。これが Strong consistency の保証。
違いの図解
| Spanner | CockroachDB | |
|---|---|---|
| 時計 | TrueTime(GPS + 原子時計) | HLC(NTP + logical counter) |
| Consensus | Paxos | Raft |
| Commit Wait | 1-7ms(不確実性) | なし or 短い |
| Linearizability | あり | あり(条件付き) |
| インフラ | GCP 専用 | Commodity HW |
| Multi-region 書き込み | 数十 ms | 数十〜数百 ms |
CockroachDB の弱点
CockroachDB のアプローチには Read after write の例外 がある(“The New Enemy” 問題):
因果関係のある 2 つの transaction で、因果順序が逆転して見える 可能性がある(極めて稀だが理論的に存在)
これは TrueTime のような物理保証がないことの代償。実用上はほぼ問題にならないが、強い consistency が要件のシステム(権限管理など)では Spanner のほうが安全。
NewSQL は OLTP の地理分散版
NewSQL は基本的に OLTP の地理分散版。SQL インターフェース、ACID、行指向(または行+列のハイブリッド)。第 3 章の 6 軸では:
- read/write: read 寄り
- レイテンシ: 数十 ms(geo 跨ぎ) / ms(同一 region)
- 整合性: Linearizable
- データ形状: 行(SQL)
- 寿命: Warm
- スケール: Geo-distributed
つまり「強整合性が必要 + 地理分散 + ACID + SQL」というニッチに特化している。
何のために使うか
graph TB
Q{要件は?}
Q -->|単一 region で OK| RDB[PostgreSQL / MySQL]
Q -->|地理分散で eventual 可| NoSQL[DynamoDB Global Tables / Cassandra]
Q -->|地理分散で Strong 必要| NewSQL[Spanner / CockroachDB]
Q -->|分析の地理分散| DWH[BigQuery / Snowflake]
style NewSQL fill:#e1f5ff
実用上、NewSQL が必要になる場面は限られる:
- 金融取引:複数地域から同時アクセス、強整合性必須
- マルチリージョン SaaS:tenant が地域に紐づくが、全体で一貫性
- 権限管理:authz の判定が逆転すると致命的
- 全世界同時更新が要件:物理的にこれが必要なドメイン
「マルチリージョンだから NewSQL」は短絡。強整合性が本当に必要かを問い直すと、多くのシステムは region ごとに独立した RDB + non-strong な同期で済む。
CAP の現代的解釈:PACELC
PACELC 定理 は CAP の拡張:
P(Partition 時)には A or C を選ぶ。E(Else、通常時)には L(Latency) or C(Consistency)を選ぶ。
| DB | P 時 | 通常時 | 略号 |
|---|---|---|---|
| RDB(単一 node) | A | L(or C) | EL/A or EC/A |
| Cassandra | A | L | PA/EL |
| DynamoDB(eventual) | A | L | PA/EL |
| Spanner / CockroachDB | C | C | PC/EC |
| Postgres + sync replication | A | C | PA/EC |
通常時にも latency vs consistency のトレードオフがあることを明示する。Spanner は通常時も commit wait の分のレイテンシを払って強整合性を取る。
この章の要点
- NewSQL は「地理分散 + Strong consistency + SQL + ACID」の交差点
- Spanner: TrueTime(GPS + 原子時計)+ Commit Wait で外部整合性
- CockroachDB: HLC + Raft で commodity hardware で類似の保証
- 違い: TrueTime は物理的、HLC は論理的。Spanner の方が安全だが GCP 専用
- 「マルチリージョンだから NewSQL」は短絡。強整合性が本当に必要かを問う
- PACELC で通常時の latency vs consistency もトレードオフとして明示
次章への問いかけ
地理分散の強整合性は手に入る。だがそれは Aggregate を地理に縛る制約を連れてくる。
次章で NewSQL の設計編。Region 配置・Locality の選び方・Consistency level の使い分けを扱う。