【実務・中級編】 インデックスのバックフィル – Cloud Spanner

Cloud Spannerのインデックス・バックフィル:数億行の海で「止まらない」ための設計哲学

エンジニア諸君。本番稼働中の巨大なテーブルにインデックスを追加する際、「どれくらい時間がかかるのか」「サービスに影響はないのか」と不安になった経験はないだろうか?

Cloud Spannerにおけるインデックス作成は、単なるDDL発行ではない。それは「分散システム全体を巻き込んだ壮大な非同期バックフィル」だ。今回は、このプロセスの内幕と、プロフェッショナルとして踏むべき現実的な設計パターンを伝授する。

—

1. 舞台裏:インデックス・バックフィルはどう動いているか

Spannerで `CREATE INDEX` を実行した瞬間、その裏側では何が起きているのか。公式ドキュメントには「非同期で処理される」とあるが、具体的には以下のフェーズを通過する。

1. メタデータ更新: スキーマ変更がコミットされ、インデックスが `CREATING` 状態になる。
2. 全スキャンとビルド: Spannerの各スプリット(データ分割単位)が独立して、既存の全データをスキャンし、インデックス用のキー・バリューペアを生成する。
3. マージと適用: 生成されたインデックスエントリがインデックス用テーブル(Spanner内部テーブル)へ書き込まれる。
4. オンライン切り替え: バックフィルが完了すると、自動的に `READY` 状態へ移行し、以降のクエリで使用可能になる。

ここが重要だ: このプロセス中、アプリケーションの読み書きは止まらない。Spannerは分散トランザクションの整合性を保ちながら、裏で黙々とデータを構築し続ける。だが、この「裏側の負荷」を無視して運用するのは、海図を持たずに荒海へ出るようなものだ。

2. 完了までの時間を「読み解く」術

「いつ終わるのか?」という問いに対し、Spannerコンソールや `INFORMATION_SCHEMA.SPANNER_STATISTICS` を眺めるだけでは不十分だ。

  • データ量との比例関係: バックフィル速度は、サーバーのノード数とスプリット数に依存する。ノードが多ければ並列度も上がるが、同時にバックフィルが消費するCPUリソースも増大する。
  • 観測の鉄則: `SPANNER_DDL_OPERATIONS` ビューを監視せよ。ここで処理の進捗率(Progress)を確認できる。

— 現在実行中のDDL操作の進捗を確認する
SELECT
OPERATION_ID,
TABLE_NAME,
STATE,
PROGRESS_PERCENTAGE, — 0.0〜100.0で進捗が可視化される
START_TIME
FROM
SPANNER_DDL_OPERATIONS
WHERE
STATE = ‘RUNNING’;

3. 実務で「詰まない」ための設計パターン

インデックス追加で失敗するエンジニアの多くは、「後先考えずに追加する」か「負荷を考慮せずピーク時に実行する」かのどちらかだ。

パターンA:インデックス・ストレージの急増を見越す

インデックスを追加すれば、当然その分のストレージ使用量は増える。特に、頻繁に更新されるカラムにインデックスを貼る場合、インデックス更新のための書き込みI/Oが、既存のデータ書き込みI/Oに上乗せされる。

  • 教訓: インデックス追加前に、現在のCPU使用率がすでに60%を超えていないか確認せよ。余裕がないなら、まずはノード増設(またはオートスケーリングの設定)が先だ。

パターンB:NULL許容カラムへの注意

多くのエンジニアが見落とすのが、`NULL` 値の扱いだ。Spannerのインデックスはデフォルトで `NULL` 値をインデックスエントリに含めない(あるいは含めるオプションを選択できる)。大量の `NULL` が存在するカラムへのインデックス追加は、物理的なデータ量以上に、クエリ実行計画の複雑化を招く可能性がある。

パターンC:段階的なデプロイ(Shadow Indexing)

もしあなたがミッションクリティカルなシステムの担当なら、以下の手順を踏め。
1. ステージング環境での計測: 本番同等のデータボリュームを投入し、バックフィルにかかる時間を計測する。これが唯一の「信頼できる予測」だ。
2. 低負荷時間帯の狙い撃ち: 可能であれば、トラフィックの谷間で実行する。
3. クエリの検証: `READY` になった瞬間に、期待するインデックスが使われているか `EXPLAIN ANALYZE` で確認する。

4. チーフアーキテクトからの忠告

最後に、これだけは覚えておいてほしい。

「インデックスは『便利』だが『無料』ではない」

インデックスを増やすほど、書き込みのレイテンシは確実に劣化する。クエリを速くするためにインデックスを追加し、その結果として書き込み性能が落ち、システム全体がボトルネックになる……これはSpanner運用の典型的なアンチパターンだ。

あなたが追加しようとしているそのインデックスは、本当に必須か?
「読み取り速度」を改善したいだけなら、マテリアライズドビューや、検索エンジン(Cloud Search等)へのオフロード、あるいはアプリケーション側のキャッシュ戦略の方が、長期的には堅牢なアーキテクチャになるかもしれない。

Spannerを使いこなすとは、単にSQLを叩くことではない。「データがどう配置され、どう移動し、どう整合性を保っているか」という、その裏側の呼吸を感じ取ることだ。

さあ、設計書に戻ろう。今の設計は、1年後のデータ量でも耐えうるか? 健闘を祈る。

コメント

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