【テクニカル・上級編】 インデックスのバックフィルプロセス – Cloud Spanner

巨大な負債を抱えるな:Cloud Spannerの「インデックス・バックフィル」を制御する深層アーキテクチャ

Cloud Spannerを単なる「リレーショナルなNoSQL」と見なしているなら、それは大きな誤解だ。この分散データベースの真髄は、Paxosによる一貫性と、スプリット(Split)という単位で動的に再配置されるデータ分割メカニズムにある。

既存の大規模テーブルに新しいインデックスを追加する際、Spannerは単なるDDL操作を行っているわけではない。バックグラウンドで走る「バックフィル(Backfill)」プロセスは、極めて高度な分散トランザクションと、負荷を制御する動的スケジューラが複雑に絡み合った、Spannerのエンジニアリングの結晶である。

今回は、このバックフィルが内部でどう動き、我々エンジニアがどのような「死の淵」を避けるべきかについて、極限まで深掘りする。

—

1. インデックス・バックフィル:内部の「非同期分散スキャン」

`CREATE INDEX` を実行した瞬間、SpannerのControl Planeは即座にメタデータを更新するが、実データの構築は非同期で行われる。これを「バックフィル」と呼ぶ。

内部的には以下のステップを、全スプリットに対して並列的かつ段階的に実行している。

1. スナップショット・リード: 既存のデータを、現在のタイムスタンプ(T_start)で一貫性を保ちつつ読み取る。
2. 分散ビルド: 各スプリットが自律的にインデックスエントリを生成する。
3. マージ・コミット: 生成されたインデックスレコードを、バッチ化されたトランザクションで書き込む。

ここで重要なのは、「負荷の分離」だ。Spannerはバックフィルが本番トラフィックを圧迫しないよう、適応的なレート制限をかけている。しかし、データサイズがテラバイト規模に達すると、この「適応」が逆に仇となり、バックフィルが何日も終わらないという事態を引き起こす。

2. バックフィルの進捗監視:限界を知る術

バックフィルのステータスは、`INFORMATION_SCHEMA.INDEX_OPERATIONS` を覗く以外に道はない。熟練のアーキテクトであれば、以下のクエリを「定点観測」すべきだ。

— 現在進行中のインデックス作成オペレーションを監視するクエリ
SELECT
TABLE_NAME,
INDEX_NAME,
STATE,
— 進捗率の推移を時系列で監視することが重要
PROGRESS_PERCENTAGE,
START_TIME
FROM
INFORMATION_SCHEMA.INDEX_OPERATIONS
WHERE
STATE = ‘RUNNING’;

もし `PROGRESS_PERCENTAGE` が数時間動かない場合、それは単なる遅延ではない。「スプリットの極端な偏り」または「ロック競合によるリトライの嵐」を疑え。

3. アーキテクトが避けるべき「バックフィルの地雷」

インデックスのバックフィルを成功させるには、以下の3つの「ハードル」を越える必要がある。

A. ライブトラフィックとの競合を最小化せよ

バックフィルは書き込みリソース(Paxosグループのログ書き込み)を消費する。書き込み頻度の高いテーブルにインデックスを追加すると、競合により本番のレイテンシがスパイクする。
対策: `STORING` 句を過度に使用せず、必要なカラムのみをインデックスに含めろ。インデックスのサイズは書き込み増幅率(Write Amplification)に直結する。

B. インタリーブ(Interleave)の罠

親テーブルに依存する子テーブルに対しインデックスを張る場合、物理的なデータ配置の局所性が重要になる。親テーブルがスプリット間で大きく偏っていると、インデックスのバックフィルも特定のノードに集中し、そのノードがボトルネックとなってシステム全体をスローダウンさせる。

C. 「読み取り専用」のバックフィル戦略

データ量が数TBを超える場合、`CREATE INDEX` を直接実行するのではなく、以下の戦略をとるべきだ。

1. 新テーブルへのDataflow移行: 大規模データであれば、バックフィルを待つよりも、Dataflow等を使用して別テーブルにインデックス付きで書き出す方が、安定性と予測可能性が高い。
2. DDL実行のタイミング: クライアントの読み書きが最も少ない時間帯を狙うのは当然だが、Spannerの負荷が「CPU 60%以下」の状態で実行することを強く推奨する。

4. 最後に:伝説となるために

Cloud Spannerにおけるインデックス作成は、単なるDDLではない。それは「稼働中のエンジンを止めずに、内部のインフラ構造を再構築する外科手術」だ。

インデックスの数だけメモリとCPUを消費し、書き込み性能が低下する。真のアーキテクトは、必要なインデックスを「最小限」に絞る。不要なインデックスは技術的負債であり、その負債はバックフィルという形で、最も忙しい時間帯に牙を剥く。

「いつでもインデックスを張れる」というSpannerの柔軟性を信じすぎるな。物理的なデータ配置(データモデル)とインデックスの相関を理解した者だけが、この分散データベースの支配権を握ることができる。

次回の運用改善では、`INDEX_OPERATIONS` のログだけでなく、`SPANNER_SYS.QUERY_STATS_TOP_MINUTE` と突き合わせて、バックフィルがどの程度Paxosのログ書き込みを圧迫しているか、その「相関」を可視化してみせよ。そこからが、本当のエンジニアリングだ。

コメント

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