はじめに
12 日のアドベントカレンダーで NewSQL に触れ、13 日・14 日のアドベントカレンダーで TiDB と CockroachDB をそれぞれローカルで構築して実際に触ってみました。
本記事ではこの 2 つの 異なる NewSQL データベースを比較し、それぞれの特徴や違いを整理しながらそれぞれのデータベースの特性への理解を深めていきたいと思います。
基本情報の比較
| 項目 | TiDB | CockroachDB |
|---|---|---|
| 開発元 | PingCAP | Cockroach Labs |
| 初版リリース | 2017 年 | 2017 年 |
| ライセンス | Apache 2.0 | BSL / CCL |
| SQL 互換性 | MySQL 互換 | PostgreSQL 互換 |
| 実装言語 | Go + Rust(TiKV) | Go |
アーキテクチャの違い
TiDB
TiDB は計算層とストレージ層が分離した 3 層構造を採用しています。
| コンポーネント | 役割 |
|---|---|
| TiDB Server | MySQL プロトコルを公開するステートレスな SQL 層。SQL の解析・最適化・実行を担当 |
| TiKV | 分散トランザクショナル Key-Value ストレージ。実際のデータを保存 |
| PD (Placement Driver) | クラスタのメタデータ管理、データスケジューリング、トランザクション ID の割り当て |
この設計により、計算リソースとストレージリソースを独立してスケーリングできます。
独立スケーリングのメリット
例えば分析クエリが増えた場合は TiDB Server(計算層)だけを追加し、データ量が増えた場合は TiKV(ストレージ層)だけを追加できます。
CockroachDB
CockroachDB は単一バイナリで動作し、内部的に 5 つのレイヤーで構成されています。
| レイヤー | 役割 |
|---|---|
| SQL Layer | SQL を Key-Value 操作に変換 |
| Transaction Layer | ACID トランザクションの実装、並行操作の調整 |
| Distribution Layer | データの分散配置、Range の管理 |
| Replication Layer | Raft による複製、リースホルダーの管理 |
| Storage Layer | Pebble エンジンによるディスク書き込み |
各ノードが対等(symmetric)に動作し、どのノードにリクエストを送っても処理できます。
分散トランザクションの仕組み
両者とも Two-Phase Commit (2PC) をベースにしていますが、実装方法が異なります。
2PC とは分散システムで複数ノードにまたがるトランザクションを「全部成功」か「全部失敗」にするためのプロトコルです。これにより ACID 特性の原子性を分散環境で保証できます。
TiDB
TiDB は Google Percolator ベースの 2PC を採用しています。
- 開始
- PD からタイムスタンプを取得し、スナップショットを固定
- Prewrite
- 全キーに対して競合確認と暫定ロック
- Commit
- プライマリキーで最終確定
v3.0.8 以降は悲観的トランザクションがデフォルトになりました。これは MySQL と同じ動作モデルで、書き込み時に即座にロックを取得することでコミット時の競合を削減します。
CockroachDB
CockroachDB は Write Intent と Parallel Commits という仕組みを採用しています。
Write Intent は書き込み時に作成される暫定値で、MVCC の値とトランザクションレコードへのポインタを含みます。従来の 2PC における「prepare」フェーズに相当します。
Parallel Commits は 2019 年に導入された最適化で、prepare フェーズと commit フェーズを並列化します。これにより、コミット時のレイテンシが 2 ラウンドから 1 ラウンドに短縮されます。
データ配置とレプリケーション
両者とも Raft コンセンサスアルゴリズムを使用してデータを複製します。
Raft コンセンサスアルゴリズムとは分散システムで複数ノードが同じデータを持つことを保証するアルゴリズムです。1 台のリーダーが書き込みを受け付け、フォロワーに複製します。過半数が合意すれば OK とするため、全員の応答を待たずに処理を進められ、一部ノードが落ちてもデータが失われません。
TiDB
TiDB はデータを Region という単位で管理します。
- Region はキー空間の連続したセグメント(デフォルト 256 MiB)
- 各 Region は複数ノードに複製され、Raft グループを形成
- PD がクラスタ全体に Region を均等に分散させるスケジューリングを担当
CockroachDB
CockroachDB はデータを Range という単位で管理します。
- Range はキー空間の連続したチャンク(デフォルト 64 MiB)
- 各 Range はデフォルトで 3 ノードに複製
- Leaseholder が読み書きリクエストを処理し、Raft でフォロワーに複製
| 項目 | TiDB | CockroachDB |
|---|---|---|
| データ単位 | Region(256 MiB) | Range(64 MiB) |
| スケジューラ | PD(専用コンポーネント) | 各ノードに分散 |
| コンセンサス | Raft | Raft |
ユースケースの違い
TiDB が向いているケース
-
MySQL からの移行
- MySQL プロトコル互換のため、既存の MySQL アプリケーションを移行しやすい
- HTAP ワークロード
- TiFlash により、OLTP と OLAP を単一プラットフォームで処理可能
- 読み取り重視のワークロード
- 読み取り集約的なワークロードや分析クエリに強い
- 計算・ストレージの独立スケーリング
- 計算リソースとストレージリソースの需要が不均等な場合
CockroachDB が向いているケース
- PostgreSQL からの移行
- PostgreSQL 互換のため、既存のツールやライブラリを利用可能
- 書き込み重視のワークロード
- 書き込み集約的なワークロードに向いている
- シンプルな運用
- 単一バイナリで動作し、「ノードを追加する」だけのシンプルなスケーリングモデル
- グローバル分散
- 地理的に分散したデプロイメントでの利用
まとめ
- TiDB と CockroachDB はどちらも 2017 年にリリースされた NewSQL データベースで、Raft を使った分散アーキテクチャを持つ
- TiDB は MySQL 互換で計算・ストレージ分離型、CockroachDB は PostgreSQL 互換で単一バイナリ型という違いがある
- TiDB は HTAP や読み取り重視のワークロードに、CockroachDB は書き込み重視やシンプルな運用を求める場合に向いている
- どちらが優れているかは一概には言えず、ワークロードや運用要件に応じて選択することが重要