designing-multi-region-applications について
designing-multi-region-applicationsは、アプリケーションの読み書き要件に応じてCockroachDBのマルチリージョン構成を選ぶスキルです。レイテンシ、トポロジーの検証、デモ手順も扱います。
主な機能
- 01マルチリージョンのテーブルと分割方式の比較
- 02読み書き要件に応じた配置方式の選択
- 03GLOBALとREGIONAL BY ROWの評価
- 04リースホルダー配置とゾーン設定の検証
- 05デモと移行の計画
活用シーン
- 01マルチリージョンアプリのデータ配置選定
- 02リージョン間の読み書きと耐障害性の設計
- 03設定後のリースホルダー分布の確認
- 04構成デモや移行の準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cockroachlabs/ cockroachdb-skills --skill designing-multi-region-applicationsインストール後、Claude Code で/designing-multi-region-applicationsを入力して読み込まれたか確認します。
詳細
マルチリージョンアプリケーションの設計
CockroachDB アプリケーションに適したマルチリージョンパターンの選択方法と、適切な検証を行いながら実装する方法について説明します。通常のリージョナルテーブル、REGIONAL BY ROW、GLOBAL テーブル、手動による地理的パーティショニングの選択モデルに加え、各アプローチを比較するための実践的なデモフレームワークを取り上げます。
他のスキルとの補完関係: トランザクション設計パターンについては、designing-application-transactions を参照してください。SQL 構文とスキーマ設計については、cockroachdb-sql を参照してください。
このスキルを使用する場面
- CockroachDB でマルチリージョンの読み取り/書き込み動作をどうモデル化するかを決める場合
- アクティブ/アクティブとアクティブ/パッシブのアーキテクチャを選ぶ場合
REGIONAL BY ROWと手動による地理的パーティショニングを評価する場合GLOBALテーブルの動作とトレードオフを理解する場合- 複数リージョンでローカルの読み取りと書き込みを設計する場合
- マルチリージョンのデモやワークショップを構築または実施する場合
- リースホルダーの配置とゾーン設定を検証する場合
- リージョン間のトランザクションレイテンシーを最適化する場合
このスキルを使用しないでください。 質問が SQL 構文、インデックス作成、またはマルチリージョンに関する判断を伴わない一般的なスキーマ設計だけに関する場合。
前提条件
- CockroachDB のレンジアーキテクチャとリースホルダーの概念を理解していること
- 以下の例で使用するリージョンに一致する
--locality=region=...,zone=...を指定してノードを起動したマルチリージョンクラスター。ローカリティーが一致しないと、DDL でregion "..." does not existエラーが発生し、+region=...のような制約に一致するノードがなくなります。ローカルで最も手早く実行する方法:
長期間実行するクラスターについては、setting-up-local-cluster を参照し、各# 9-node demo with three regions, three AZs each — note --no-example-database cockroach demo --no-example-database --nodes=9 \ --demo-locality=region=NA-NE,az=1:region=NA-NE,az=2:region=NA-NE,az=3:region=NA-MW,az=1:region=NA-MW,az=2:region=NA-MW,az=3:region=EU-DE,az=1:region=EU-DE,az=2:region=EU-DE,az=3cockroach start呼び出しに--locality=region=...,zone=...を追加してください。 - アプリケーションの書き込みパターンに関する知識(単一リージョンか複数リージョンか)
パターンの選択
ステップ 1:アプリケーションの書き込みモデルを特定する
最初に、**書き込み先は 1 か所ですか、それとも複数ですか?**と確認します。
- アプリケーションの読み取り/書き込み用のプライマリーリージョンが1 つの場合は、プライマリーリージョン/通常のリージョナルテーブルモデル、または手動で設定するアクティブ/パッシブ設計から始めます。
- アプリケーションで複数リージョンの低レイテンシーな読み取り/書き込みが必要な場合は、手動による地理的パーティショニングまたは
REGIONAL BY ROWを評価します。 - テーブルが主に、どこからでも高速に読み取れるようにする参照データであり、書き込みパスが主な焦点ではない場合は、
GLOBALテーブルを検討します。
ステップ 2:パターンを選択する
A. 通常のリージョナルテーブル(アクティブ/パッシブ)
次の場合に使用します:
- アプリケーションの RW 用プライマリーリージョンが 1 つである
- リモートリージョンがセカンダリー、または主に読み取り専用である
- すべてのリージョンでのローカル書き込みよりもシンプルさを重視する
特性:
- すべてのリースホルダーがアクティブリージョンにとどまる
- 他のリージョンのレプリカにより、回復性と単一リージョン障害への耐性が得られる
- 目安となるレイテンシー:約 20ms の書き込み、約 2~5ms の読み取り(ローカルリージョン)
推奨: パーティション、投票者、リース設定を手動で制御する必要があるとユーザーが明示している場合を除き、まずはより高レベルなマルチリージョン抽象化を優先してください。
B. リージョン固有のリースホルダーを使用した手動の地理的パーティショニング
次の場合に使用します:
- アプリケーションがアクティブ/アクティブである
- データモデルがリージョンキーを持つ
- チームが運用を明示的に制御したい
- 内部の仕組み(パーティション、投票者、リース設定)の理解が重要である
特性:
- リージョン固有のリースホルダーパターンにより、書き込みは約 20ms、読み取りは約 2~5ms に保たれる
- アプリケーションは、同じリージョン内でキーに対する読み取りと書き込みを行うよう徹底する必要がある
- DDL と運用の負担が増える
- 内部の仕組みを教える用途に最適
DDL の例:
CREATE TABLE accounts_manual (
account_id STRING(40),
owner_id STRING(40) NOT NULL,
status STRING(20) NOT NULL,
region STRING(10) NOT NULL,
CONSTRAINT accounts_manual_pkey PRIMARY KEY (region, account_id)
);
ALTER INDEX accounts_manual_pkey
PARTITION BY LIST (region) (
PARTITION na_ne VALUES IN ('NA-NE'),
PARTITION na_mw VALUES IN ('NA-MW'),
PARTITION na_nw VALUES IN ('NA-NW')
);
ALTER PARTITION na_ne OF INDEX accounts_manual_pkey
CONFIGURE ZONE USING
num_replicas = 5,
num_voters = 5,
voter_constraints = '{+region=NA-NE: 2, +region=NA-MW: 2, +region=NA-NW: 1}',
lease_preferences = '[[+region=NA-NE]]';
C. 行単位のリージョン設定(REGIONAL BY ROW)
次の場合に使用します:
- ワークロードがアクティブ/アクティブである
- 各行が自然にいずれかのリージョンに属する
- パーティションのゾーン設定を手動で管理せずに、複数のリージョンでローカルな読み書きを行いたい
- 開発者向けのマルチリージョン抽象化が目的である
特性:
- 設定されたすべてのリージョンを、ホームリージョン/リースホルダーリージョンにできます
- 目安となるレイテンシ:書き込み約20ms、読み取り約2~5ms(ローカルリージョン)
- ジオパーティショニングより手動設定が少なくて済みます
- リージョンに関連付けられたアプリケーションデータのデフォルトの推奨方式です
DDL の例:
CREATE DATABASE IF NOT EXISTS example_service_rbr;
ALTER DATABASE example_service_rbr PRIMARY REGION 'NA-NE';
ALTER DATABASE example_service_rbr ADD REGION 'NA-NW';
ALTER DATABASE example_service_rbr ADD REGION 'NA-MW';
ALTER DATABASE example_service_rbr SURVIVE REGION FAILURE;
USE example_service_rbr;
CREATE TABLE accounts_rbr (
account_id STRING(40),
owner_id STRING(40) NOT NULL,
status STRING(20) NOT NULL,
region crdb_internal_region
NOT NULL
DEFAULT gateway_region()::crdb_internal_region,
CONSTRAINT accounts_rbr_pkey PRIMARY KEY (region, account_id)
) LOCALITY REGIONAL BY ROW AS region;
ローカル割り当てパターン:
WITH candidate AS (
SELECT id, resource_code
FROM resource_pool
WHERE allocated_at IS NULL
AND region = gateway_region()::crdb_internal_region
ORDER BY random()
LIMIT 1
FOR UPDATE
)
UPDATE resource_pool
SET allocated_at = now()
WHERE id = (SELECT id FROM candidate);
D. GLOBAL テーブル
次の場合に使用します:
- テーブルがグローバルな参照スタイルのデータである
- ワークロードの主な目的が、リージョンごとの書き込みではなく、幅広い読み取りローカリティである
重要な制約: GLOBAL テーブルは、あらゆる場所での高速な読み取りを最適化します。公式ドキュメントで製品固有の動作を確認せずに、「あらゆる場所で読み書きできる」パターンとして位置付けないでください。
E. 障害耐性目標
書き込みレイテンシと耐久性のトレードオフに基づいて、障害耐性目標を選択してください。
-- Survive any single zone failure (default, 3+ zones required):
ALTER DATABASE mydb SURVIVE ZONE FAILURE;
-- Survive an entire region going down (3+ regions required):
ALTER DATABASE mydb SURVIVE REGION FAILURE;
| 目標 | 要件 | 書き込みレイテンシ | データの安全性 |
|---|---|---|---|
| SURVIVE ZONE FAILURE | 3つ以上のゾーン | 低(ローカルでのコンセンサス) | 1つのゾーンの障害に耐えます |
| SURVIVE REGION FAILURE | 3つ以上のリージョン | 高(リージョン間のコンセンサス) | 1つのリージョンの障害に耐えます |
SURVIVE REGION FAILURE では、Raft コンセンサスがリージョン間にまたがるため書き込みレイテンシが増加しますが、クラウドリージョン全体がオフラインになってもデータが失われないことが保証されます。
パターンの比較
| 項目 | 通常のリージョン構成 | 手動ジオパーティショニング | 行単位のリージョン設定(REGIONAL BY ROW) | GLOBAL |
|---|---|---|---|---|
| 書き込みモデル | 単一のプライマリーリージョン | アクティブ/アクティブ、リージョンキーによる | アクティブ/アクティブ、行に応じたリージョン | プライマリーリージョンから書き込み |
| 読み取りローカリティ | プライマリーにローカル | パーティションにローカル | 行のリージョンにローカル | すべてのリージョン |
| 運用負荷 | 低 | 高 | 中 | 低 |
| 設定 | 最小限 | 明示的なパーティション、ゾーン、リースの優先設定 | データベースレベルの抽象化 | テーブルレベルの宣言 |
| 最適な用途 | シンプルなプライマリーリージョンアプリ | 仕組みを完全に制御したい場合 | 開発者向けのマルチリージョン | 参照データ |
ライブデモのセットアップ
ワークショップや技術的なウォークスルーでは、マルチリージョンのローカリティを確認できるよう、9ノードのローカルデモクラスターを使用してください。
クラスターのセットアップ
cockroach demo \
--nodes 9 \
--no-example-database \
--insecure \
--demo-locality=\
region=NA-NE,zone=NA-NE-1:\
region=NA-NE,zone=NA-NE-2:\
region=NA-NE,zone=NA-NE-3:\
region=NA-MW,zone=NA-MW-1:\
region=NA-MW,zone=NA-MW-2:\
region=NA-MW,zone=NA-MW-3:\
region=NA-NW,zone=NA-NW-1:\
region=NA-NW,zone=NA-NW-2:\
region=NA-NW,zone=NA-NW-3
デモの流れ
推奨する説明順:
- 手動ジオパーティショニングの手順から始めます
- 明示的なパーティショニングとゾーン設定を示します
- 検証クエリを実行し、リースの配置を確認します
- 行単位のリージョン設定(REGIONAL BY ROW)に切り替えます
- RBR の検証を実行します
- 運用上の設定範囲を比較します
検証クエリ
手動パーティショニングの検証:
SHOW RANGES FROM INDEX accounts_manual_pkey WITH DETAILS;
以下を確認します:
- 予想されるすべてのパーティション値が存在すること
- リースホルダーのローカリティがパーティションのリージョンと一致すること
- 不一致があれば FAIL が返され、それ以外は PASS が返されること
RBR の検証:
SHOW RANGES FROM TABLE accounts_rbr WITH DETAILS;
以下を確認します:
- リースホルダーのローカリティに、予想されるリージョンが含まれていること
- 予期しないリースリージョンがないこと
デモで説明するポイント
手動の手順:
- パーティション、投票者、レプリカ、リースの優先設定を正確に制御できます
- DDL と運用上の負担が増えます
- 内部の仕組みを教え、データベースが内部で行っていることを理解するのに最適です
RBR の手順:
- アプリケーションの意図を最優先に保てます
- 手動設定が少なくて済みます
- アプリチームにとって説明しやすくなります
- 同じトポロジーに基づいています
クロスリージョンのレイテンシに関するガイダンス
クライアントが関連するリースホルダー/クォーラムの経路から離れた場所にある場合、トランザクションのレイテンシは増加します。
| クライアントの場所 | ローカル RW レイテンシ | クロスリージョン RW レイテンシ |
|---|---|---|
| リースホルダーと同じリージョン | ~10-20ms | — |
| 別のリージョン | — | ~50-150ms+ |
ガイダンス:
- レイテンシに敏感なサービスは、主要なデータのローカリティに近い場所に配置します
- 重要度の低い表示/レポート用クエリにはフォロワー読み取りを使用します
- マルチリージョンのテーブルローカリティとゾーン構成を意図的に使用します
- 「分散型」だからといって「どこでも同じレイテンシ」だと考えないでください
出力に関する要件
このスキルを使った優れた回答には、次の内容を含めます。
- 推奨されるパターン
- それがワークロードに適している理由
- アプリケーション側で必要な対応(ルーティング、行のアフィニティ、プライマリーリージョンに関する前提)
- CockroachDB が自動的に管理するものと、手動で管理するもの
- 想定されるレイテンシの形態やローカリティの動作
- ユーザーが、選択したパターンでは最適化されない要件を求めている場合の警告
ガードレール
- 通常のプライマリーリージョンテーブルが、すべてのリージョンから対称的な低レイテンシの書き込みを提供すると主張しないでください
- 裏付けとなるドキュメントなしに、
GLOBALが全リージョンで低レイテンシの書き込みを実現する答えだと主張しないでください - 手動のジオパーティショニングと
REGIONAL BY ROWを比較する場合は、制御性とシンプルさの違いを明示してください - ユーザーが内部の仕組みを理解したい場合は、まず手動のモデルを説明することを優先してください
- ユーザーが最適なデフォルトのアプリケーションパターンを求めている場合は、リージョンにアフィニティを持つデータに
REGIONAL BY ROWを優先してください - すべての SQL でリージョン名とローカリティラベルを統一してください
- 明示的に比較する場合を除き、同じ説明で手動方式と抽象化方式を混在させないでください
- DDL だけでなく、必ず検証方法も含めてください
マルチリージョン移行チェックリスト
単一リージョンの PostgreSQL/Oracle からマルチリージョンの CockroachDB に移行するチーム向け:
--locality=region=<region>,zone=<zone>を指定してノードをデプロイします- プライマリーリージョンを設定します:
ALTER DATABASE <db> PRIMARY REGION '<region>' - リージョンを追加します:
ALTER DATABASE <db> ADD REGION '<region>'(各リージョンに対して実行) - サバイバビリティ目標を設定します:
ALTER DATABASE <db> SURVIVE ZONE|REGION FAILURE - テーブルを分類します:GLOBAL(参照データ)、REGIONAL BY ROW(行アフィニティあり)、REGIONAL BY TABLE(デフォルト)
- ローカリティを設定します:
ALTER TABLE <t> SET LOCALITY <locality> - DB Console でリースホルダーの分散状況を監視します
- フェイルオーバーをテストします:ゾーン/リージョンを停止し、サバイバビリティ目標が維持されることを確認します
安全に関する考慮事項
- マルチリージョン構成の変更は、クラスター全体のデータ配置に影響します
- 本番環境に適用する前に、デモ環境またはステージングクラスターでマルチリージョン構成をテストしてください
- 構成変更後にリースホルダーの配置を検証してください
- トポロジーの変更後、レンジの再バランスに必要な時間を確保してください
参考資料
- CockroachDB マルチリージョンの概要
- REGIONAL BY ROW テーブル
- GLOBAL テーブル
- フォロワー読み取りのドキュメント
- CockroachDB トランザクション
- パフォーマンスのベストプラクティス
- トランザクションに対するクロスリージョンレイテンシの影響
- CockroachDB におけるクエリの並列処理
- CockroachDB のベストプラクティスとアンチパターンのデモ -- デモ 10 では、実行可能な例を使ってマルチリージョンのパターンを解説します