【実務・中級編】 データ移行戦略 – Cloud Spanner

Cloud Spannerへの移行:RDBMSの「常識」を捨て、分散データベースの「真理」に最適化せよ

世の中の多くのエンジニアが、Cloud Spannerを「ただのマネージドなMySQLの延長」だと勘違いしている。そして、その誤解こそが移行プロジェクトを失敗させる最大の要因だ。

私はこれまで数多くの大規模システムをSpannerへ移行させてきたが、成功したチームには共通点がある。それは、「RDBMSのアンチパターンをSpannerのベストプラクティスへと昇華させている」ということだ。

本稿では、レガシーRDBMSからSpannerへ移行する際、コードレビューで必ず指摘する「核心」を伝授する。

—

1. スキーマ設計:インデックスではなく「インターリーブ」で戦え

RDBMSにおいて、親テーブルと子テーブルをJOINするのは当たり前の光景だ。しかし、SpannerにおいてJOINは「ネットワーク越しの高コスト操作」になる。

インターリーブ(Interleaving)の魔法

Spannerには、子テーブルのデータを物理的に親テーブルの行の近くに配置する「テーブルのインターリーブ」という強力な武器がある。

  • RDBMSの設計: `Users` テーブルと `Orders` テーブルを別々に作成し、`user_id` でJOINする。
  • Spannerの設計: `Orders` を `Users` にインターリーブする。

— 物理的にデータが隣接するため、JOINのコストが劇的に下がる
CREATE TABLE Users (
UserId INT64 NOT NULL,
Name STRING(MAX),
) PRIMARY KEY (UserId);

CREATE TABLE Orders (
UserId INT64 NOT NULL,
OrderId INT64 NOT NULL,
OrderDate TIMESTAMP,
) PRIMARY KEY (UserId, OrderId),
INTERLEAVE IN PARENT Users ON DELETE CASCADE;

知見: 親子関係が明確なデータは、必ずインターリーブを検討せよ。これにより、物理的なデータ局所性が高まり、クエリパフォーマンスが劇的に向上する。

—

2. プライマリキー設計:ホットスポットの回避は「エンジニアの矜持」

RDBMSで「連番(AUTO_INCREMENT)」を使っていた諸君、Spannerでそれをやるとシステムが死ぬ。

Spannerはデータをキーの昇順で「スプリット」する。連番キーを使うと、常に新しいデータが特定のノードに集中し、書き込みのホットスポットが発生する。これがSpannerにおける「死」の典型だ。

推奨されるキー設計

1. UUID (v4): ランダム性を持たせ、負荷を分散させる。
2. ビット反転したシーケンス: シーケンスを使う必要がある場合、ビットを反転させることで、連続した値を広い範囲に分散させる。
3. 複合キーの工夫: 頻繁に検索される条件をプレフィックスにする。

コードレビューの視点:
「このキーは単調増加か?」と問え。もしYesなら、設計を破棄して再考するよう促すのが私の流儀だ。

—

3. 移行戦略:オンライン移行こそが「実戦」である

「停止期間を設けてダンプをリストアして…」などという移行は、モダンなシステムでは許されない。移行は常に「オンライン」で行うべきだ。

推奨される移行アーキテクチャ

1. CDC (Change Data Capture) の活用: Debezium等を用いて、既存のMySQL/PostgreSQLの更新ログをCloud Pub/Sub経由でSpannerへ流し込む。
2. デュアルライト: アプリケーション層で、旧DBとSpannerの両方に書き込む。読み込みは旧DBから行い、整合性が確認できたら徐々にSpannerへ切り替える(カナリアリリース)。
3. Dataflowによる同期: 一括移行にはDataflowテンプレートが最適だ。これを使えば、変換ロジックをスケールさせながら安全にデータを流し込める。

—

4. パフォーマンスの真実:WHERE句の「質」が全てを決める

Spannerのクエリ実行計画を甘く見てはいけない。Spannerは分散環境であるため、全ノードをスキャンするようなクエリ(フルスキャン)は、データベースを麻痺させる毒となる。

  • プライマリキーでの検索: 最速。
  • セカンダリインデックス: 有効だが、ストレージコストと書き込み負荷を考慮せよ。
  • Force Join: 複雑なJOINが必要な場合、`FORCE JOIN` ヒントを使用して実行順序を明示的に制御する勇気を持て。

現場の教訓:
「クエリが遅い」と言われたら、まずは `EXPLAIN ANALYZE` を実行せよ。そこで「Full Scan」という文字を見つけた時が、君がアーキテクトとして成長する瞬間だ。

—

最後に:移行は「破壊」ではなく「進化」である

既存のRDBMSをSpannerに持っていくことは、単なる場所の移動ではない。「スケーラビリティの制約から解放される」というパラダイムシフトだ。

設計において「これで本当にスケールするのか?」と常に自問自答すること。それが、世界最高峰のエンジニアへの唯一の道である。

さあ、古い制約を捨て、無限のスケールを手に入れよう。コードベースで、君たちの答えを見せてくれ。

コメント

タイトルとURLをコピーしました