6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

オンプレからGoogle Cloudへの大規模移行を成功させる設計術 — ファイル同期の停止時間短縮とDB整合性検証の勘所

6
Posted at

はじめに

数TB規模のオンプレ資産を Google Cloud(Cloud Storage と Cloud Spanner)へ移行するプロジェクトに参加しました。設計書レビューで顧客から繰り返し詰められたのが「件数が合えば終わり、ではない」「停止時間はどう読むのか」の2点です。

派手なアーキテクチャ刷新ではなく、設計段階で押さえておけば後工程で焦らずに済んだ勘所を、ファイル移行とDB移行の両面から整理します。これから GCS / Spanner への移行を控える方の参考になれば幸いです。

Part 1: ファイル移行 — 停止時間ゼロに近づける rsync 二段構え

問題発見: シングルカット移行は停止時間が"読めない"

オンプレのアプリケーションサーバ群から Cloud Storage へ、数百万ファイル・数TB規模のコンテンツを移します。初版の設計書では「サービス停止 → 一括 rsync → 動作確認 → 切替」というシングルカット構成でした。

レビューで指摘されたのは「実測ベースの停止時間根拠がない」点。事前検証で完走時間を計っても、当日のネットワーク負荷次第でブレが大きく、SLA上飲める停止枠に収まる保証ができませんでした。「最悪ケースで何分かかるか答えられない移行計画は通せない」というのが顧客側の本音です。

解決設計: rsync を「事前同期」と「差分同期」に分割する

gcloud storage rsync をフェーズ分割しました。

フェーズ タイミング サービス状態 転送内容
A. 事前同期 切替日の数日前から定期実行 商用稼働中 全量(初回)→ 差分(2回目以降)
B. 当日差分同期 切替当日のサービス停止後 メンテナンスモード フェーズA以降の差分のみ

gcloud storage rsyncファイルサイズと更新日時で差分判定するため、変更されていないファイルは2回目以降スキップされます。これによって当日の転送量を、おおむね「直近24時間ぶんの更新差分」まで圧縮できます。

Before / After(停止時間の試算)

方式 当日転送量 想定停止時間 SLA枠への収まり
シングルカット 数TB 数時間〜(読めない) 不可
事前同期+差分同期 数十GB(差分のみ) 分オーダー 余裕

設計上のポイント3つ

  1. 再実行可能性を前提に組む
    フェーズAは複数回流れる前提です。1回目で全量、以降は差分のみが流れるので、定期実行スケジュールに乗せても無害。むしろ「事前同期は何度でもやり直せる」という性質が、運用上の心理的安全になります。

  2. 削除フラグの扱いを慎重に
    --delete-unmatched-destination-objects を素直に付けると、事前同期期間中にクラウド側へ何らかの理由でアップロードされたオブジェクトが消えます。「移行期間中はクラウド側に書き込まない」運用と組み合わせるか、削除はフェーズBのみで有効化するかを設計書に明示しました。

  3. 権限とライフサイクルを切替前に検算
    事前同期で先行アップロードされたオブジェクトに、商用切替時のIAMポリシーやライフサイクルルールが意図通り効くかは、必ず切替前に1ファイルでも実機確認します。「同期は完璧だがACLが噛み合わず読めない」は実際に起き得ます。

検証設計: find × gcloud storage ls × md5sum の三点突合

「同期したからOK」では設計書として通りません。検証手順は次の三段で組みました。

# オンプレ側: 相対パス + サイズの一覧
find /mnt/contents -type f -printf '%P\t%s\n' | sort > onprem.tsv

# Cloud Storage 側: 同等情報を抽出して整形
gcloud storage ls -lR gs://bucket/contents/** \
  | awk '/^[^TOTAL]/ {print $NF "\t" $1}' | sort > gcs.tsv

# 一覧全体を1ハッシュに畳んで突合
md5sum onprem.tsv gcs.tsv

ポイントは find-printf '%P\t%s\n'ルートを除いた相対パスとバイトサイズを出力すること。Cloud Storage のオブジェクト名と直接突き合わせやすい形になります。

一覧をソートしてからファイル全体の md5sum を取れば、行単位 diff を取らずに「同一かどうか」を1コマンドで判定できます。数TB規模だと全ファイル個別のチェックサム取得は現実的でないので、「一覧(パス+サイズ)の整合を高速チェック → サンプル抽出で個別ハッシュ比較」の二段構えに落ち着きました。

Part 2: DB移行 — PostgreSQL→Cloud Spanner で「件数一致」は出発点

問題発見: 顧客レビューで突き返された3観点

PostgreSQL から Cloud Spanner への移行設計書を初版で出したところ、顧客レビューで以下3点を指摘されました。

  1. 検証方法の拡充 — テーブル件数とPK一致だけでは検証として弱い
  2. 移行時の制約・依頼事項の明記 — メンテナンスモードへの切替タイミング、データ静止点の定義が曖昧
  3. 役割分担・作業時間の記載 — どの工程を誰が、何分かけるのか不明

要するに「設計書として読み手が意思決定できない」状態だったわけです。特に1番は耳が痛い指摘でした。

解決設計1: 検証を5層構成に拡張

最終的に検証章を以下の5層構成に組み直しました。

レイヤ 内容 この層で検出できる事象
1. 件数検証 テーブルごとのレコード件数比較 行漏れ
2. PK一致検証 PK集合の比較(ソート後md5sum等) 抜け/重複
3. データ型変換検証 型変換ルールに沿った代表値サンプリング比較 型差異起因の値破損
4. 業務操作検証 アプリ経由の参照/更新シナリオ実施 アプリ層で初めて顕在化する不整合
5. 性能検証 主要クエリのレイテンシ確認 Spannerのインターリーブ/インデックス設計の妥当性

特に効いたのは3層目と4層目

PostgreSQL の TIMESTAMP WITH TIME ZONE と Spanner の TIMESTAMPNUMERIC の精度・スケール差、TEXTSTRING(MAX) のソート挙動差など、件数とPKだけ見ていれば必ず素通りする差分が、データ型変換検証で炙り出されます。

さらに業務操作検証(4層目)は、アプリ側のORMやドライバが想定する型と Spanner 側の実型のズレを実走で検出する最後の砦になります。「SELECT を流して値が一致」と「画面に正しく表示される」「業務処理が完走する」の間には、地味だが致命的な距離があります。

解決設計2: 制約事項と役割分担を表で明文化

「メンテナンスモードへの切替は顧客作業」「データ静止点(書き込み停止)の確認はベンダー作業」のような責任の境界を工程ごとの表で記載しました。想定時間も併記することで、レビュー時に「この工程、本当に15分で終わるんですか?」という具体性のある議論が成り立つようになります。

ここを書かないと、レビューが「何となく不安」で終わってしまい、設計書としては最悪のステータス(「再レビュー」)に落ちます。

解決設計3: 複数ツールが登場する設計書では役割分担を明記する

スキーマ生成は spanner-migration-tool schema で、データ投入は別の自作Python移行ツールで、という構成にした際、初版ではどのツールが何を担当するかの境界が曖昧でレビュー指摘を受けました。

[Before] 「移行ツールでスキーマとデータを移行する」
         → 読み手「で、結局どっちのツールが何やるの?」

[After]  ツール別の責務表を1枚追加
         | ツール | 入力 | 出力 | 責務 |
         |---|---|---|---|
         | spanner-migration-tool schema | PG DDL | Spanner DDL | スキーマ変換のみ |
         | 自作Pythonツール | PG レコード | Spanner レコード | データ投入のみ |

たった1枚の表で読み手の混乱は激減しました。

Part 3: 設計書の整合性を崩さないチェックリスト

移行設計書は、対象が途中で変わると整合性が一気に崩れます。「移行不要になったテーブルが検証対象一覧に残っている」「移行先バケットが減ったのに移行フロー図に古いバケットが残っている」は、レビューで必ず突かれます。

移行対象を変更する際に連動更新すべき4箇所を、チームのチェックリストに固定化しました。

  • 移行不要テーブル/対象一覧
  • 移行先バケット/スキーマ一覧
  • 移行フロー図(手順)
  • 検証対象リスト

1箇所だけ更新して残り3箇所を忘れる、というのが設計書全体の矛盾を生む最頻パターンです。差分PRレビュー時もこの4点を機械的にチェック観点に入れることで、整合性事故を未然に防げました。

おわりに

オンプレ → Google Cloud 移行で繰り返し顧客レビューに問われたのは、結局のところ次の2点に集約されます。

  • 停止時間を「読める形」に分解する — シングルカットではなく事前同期+差分同期で、当日の不確実性を圧縮する
  • 件数一致を出発点にする — データ型変換と業務操作の2層を必ず重ねる

派手な技術ではありませんが、設計書の質は最終的にこの「分解の細かさ」で決まる、と痛感したプロジェクトでした。

同じく GCS / Spanner への大規模移行を控えている方にとって、レビューで詰められる前に潰せる観点として参考になれば幸いです。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?