Cloud SpannerのDMLを極める:その「原子性」と「スループット」の深淵へ
Cloud Spannerを単なる「リレーショナルデータベース」だと思っているなら、今すぐその認識を捨ててほしい。Spannerは「地球規模の分散整合性エンジン」だ。
DML(INSERT/UPDATE/DELETE)の実行は、単なるSQLの投げ合いではない。それは、世界中に散らばるノード間で合意形成(Paxos)を行い、タイムスタンプを刻み、整合性を保証する極めて重厚なプロセスなのだ。
実務でSpannerを使い倒すエンジニアのために、教科書には載っていない「設計の急所」を授ける。
—
1. DMLの「裏側」を知る:なぜ「一括処理」が命なのか
Spannerで最も避けなければならないのは、「N+1のDML発行」だ。
— アンチパターン:ループ内で個別にDMLを発行する
— これをやると、1クエリごとにRPCのオーバーヘッドとコミットのオーバーヘッドが積み重なり、
— システムは一瞬でスループットの限界を迎える。
UPDATE Users SET Status = ‘Active’ WHERE UserId = ‘u1’;
UPDATE Users SET Status = ‘Active’ WHERE UserId = ‘u2’;
…
なぜこれがダメなのか?
SpannerのDMLは「トランザクション」のコンテキストで実行される。各DML発行ごとに、クライアントとサーバ間でラウンドトリップが発生し、さらに「ロック獲得」のコストが乗る。
ベストプラクティス:Batch DMLを活用せよ
`executeBatchDml`(または `Partitioned DML`)を使え。これにより、複数のDMLを1つのRPCでサーバに送り込み、サーバ側で効率的に処理することが可能になる。
—
2. 賢明なトランザクション設計:RWとROの峻別
DMLを叩く際は必ず「読み書きトランザクション(Read-Write Transaction)」に入る必要がある。ここでエンジニアが陥る罠が「トランザクションの肥大化」だ。
「読み取り」と「書き込み」の分離
1. 読み取り: 可能な限り、非ブロッキングの「読み取り専用トランザクション」や「Stale Read」を活用し、書き込みの鎖を断ち切る。
2. 書き込み: トランザクション内では、最低限必要なDMLと、その前提となる最小限のSELECTのみを行う。
設計指針:
「トランザクションの中で複雑なビジネスロジックを回すな」。
アプリケーション層で計算を済ませ、確定した結果だけをDMLで投げる。これがSpannerのレイテンシを最小化する唯一の道だ。
—
3. 分散の極致:Partitioned DMLの使いどころ
数百万件、数億件のデータを一気に更新したいとき、通常のDMLや`Mutation`では、トランザクションの有効期限(1時間)やロック競合で必ず爆発する。
ここで登場するのが Partitioned DML だ。
— 大規模データ更新の例
— Partitioned DMLは、クエリを複数の独立した小さなトランザクションに分解して並列実行する。
— ただし、注意点がある。原子性は「個々の分割されたDML単位」でしか保証されない。
— つまり、「全体が成功するか失敗するか」の保証はない。
UPDATE Users SET LastLogin = ‘2023-10-27’ WHERE LastLogin < '2023-01-01';
【プロの知見】
- 用途: 履歴データのパージ、カラムのデフォルト値一括変更など、厳密なACIDが不要なバッチ処理にのみ使うこと。
- 注意点: 実行中にエラーが発生した場合、どこまで処理が完了したかを追跡する仕組みを自前で用意する必要がある。
—
4. パフォーマンスを左右する「主キー」の呪縛
DMLのパフォーマンスは、SQL文ではなく「テーブルのスキーマ設計」で9割決まる。
- ホットスポットを避ける: DMLが特定のキー(例えば、連番や現在時刻)に集中すると、特定のSplitに負荷が偏り、レイテンシが跳ね上がる。UUIDの乱数化や、キーの反転(bit-reverse)を検討せよ。
- インデックスの代償: インデックスを貼ればSELECTは速くなるが、DMLのたびにインデックス更新のオーバーヘッドが発生する。不要なインデックスは「性能の敵」だ。
—
最後に:エンジニアへのメッセージ
SpannerのDMLを扱う際、常に自問自答してほしい。
「この更新は、本当にこのトランザクションでやるべきか?」
単一のレコード更新であれば`Mutation` APIの方がDMLよりオーバーヘッドが少なく高速な場合が多い。複雑なクエリが必要な場合のみDMLを使う。この使い分けが、あなたのシステムを「止まらない基盤」へと昇華させる。
コードを書くとき、目の前のSQLが「地球の裏側のノードでどう動くか」を想像できるようになったとき、君は真のSpannerエンジニアになれる。
さあ、コードレビューに戻ろう。今の設計、本当にスケーラブルか?
コメント