大容量DBのスムーズなクラウド移行:
運用の中での10TBデータの転送

大規模なデータベースサーバを含むシステムのクラウド移行を、サービスの中断を最小限にして完了。問題の解決策や移行手法を紹介

課題:巨大DBの壁

E社は、企業ユーザにWebサービスを提供するスタートアップ企業です。サービスは着実に成長し、契約企業やユーザ数が増加。データ量やシステムの規模が急激に大きくなっていました。システムの柔軟性を高め、メンテナンスを容易に行えること、コストの効率を追求するため、システムをオンプレミスのデータセンターからパブリッククラウドであるGoogle Cloudへ移行を計画し、まさにその真っただ中でした。

E社のシステムでは、合計で約20台のサーバーが動いています。そして、サービスは24時間365日提供しているため、サービスの停止を極力短時間にしてスムーズに移行することも大きな課題です。システムの移行プロジェクトは順次進んでいましたが、主役の10TBの巨大なデータベースサーバーの移行において、さまざまな問題が発生して作業は難航していました。

対策の提案:計画、問題と解決の繰り返し

先ずは、チームやシステムについての勉強とともに、直近で発生している問題点の把握にあたりました。発生している現象をヒアリングしてそれらの原因究明と解決策を行いました。

1)発生している既存の課題の調査と対策

先日に行った、DB移行作業ではDBのデータを転送しようとしたが、処理スピードが非常に遅く、さらに待つこと数日後に、ネットワークエラーが発生し転送が異常終了してしまったとのことでした。

処理スピードが遅すぎる

性能が出ないということで、何かボトルネックが存在するのか?もしくは、この方式ではこの処理スピードが限界なのか?を探ることにしました。 ボトルネックの可能性は送信元のデータセンターのマシン・ネットワーク機器、中継しているHW関連、受信側のGoogleCloudのマシン、ネットワークリソース全般におよびます。

いろいろ調査を進めながら、念のためお願いしたデータセンターからの手動データ転送で十分な速度が出という結果を受け、実施したタイミング固有の問題としてぐっと絞りこむことができました。さらに、データセンター側の調査を進めてもらったところ、その時行った転送の方法とマシンリソースに原因があったことが分かりました。

原因
  • 別の重たい処理がディスクIOのリソースを占有したままで、実行時に十分なリソースがなかった。
  • ファイルに関する処理がシングルスレッドで動作してしまっていた。
対策
  • ボトルネットが発生する処理中は、他の重たい処理を停止、もしくは、別ディスク別パスを利用。
  • ファイルに関する処理をマルチスレッドで動作させる。

ネットワークエラーが発生して中断

この作業は、専用線ではなく低品質な一般的なインタネット回線を利用しており、一週間弱かけて転送を行う予定です。ネットワークエラーやその他何らかの一時的な問題などで処理が中断することは十分ありうるので考慮して再設計することにしました。

対策
  • 100GBに分割して順次転送
  • 失敗したらその100GBの再送を行う
  • 全部送信し終わったら、転送先GoogleCloudのサーバで受信データを結合

これで、既存の問題について解決の道筋が立ちました。

2)計画の作成

E社はスタートアップらしく軽いフットワークのチームでしたが、この作業については、実施時間が一週間弱に及び長く、データセンターや本番サービス側の調整のコストのことなどを考え、少し腰を据えて計画を立てることにしました。

とはいえ計画は簡単なもので、関係者の頭の中の整理を目的とします。項目をリストアップして関係者でブラッシュアップします。また、ノウハウとしてナレッジ化するので次回の作業での活用が見込めます。

主な項目
  • 分かっている問題
  • 発生しそうな問題
  • 実施日時、役割分担、タイムスケジュール
  • 要所の具体的な手順
  • 完了、失敗の基準と判断

計画を作ることで、いろいろなところに考えが及ぶようになりました。

作業の全体的な流れ、関係者のスケジュールと役割、手順の検証、性能や作業時間の見積もり、作業の失敗・時間超過などのときの判断基準、失敗時の戻し方など。

3)成功するまで繰り返す

白状しますと、せっかく知見を集め、検証して計画を作り実行したにもかかわらず、失敗しました。データの転送を追え、データを結合し、ディスクをマウントし、DBサーバの起動時に起こりました。"DBサーバの初期化処理におけるテーブルエラー"。つまり、エラーが発生してDBサーバが起動しません。

再び、問題の原因について考え、計画を立て直します。有識者で手順を検証した後の考えられる原因は、「ディスクキャッシュの掃き出し漏れ」でした。

「確かにやっていない・・・」

手順に"ディスクキャッシュの掃き出し"を追加、その他の気付きの修正も加え計画をブラッシュアップし再実施します。 無事、2回目の実施で、DBサーバの起動を確認し、巨大DBサーバのクラウドへの移行が成功しました。

結果:作業を通して得たノウハウ

2回目の計画&実施、ユーザ目線で考えると2週連続の週末のシステムメンテナンスの結果、無事に20GBのデータをデータセンターからクラウドに移行し、クラウドインフラ上でのDBサーバがこのデータを使って起動できることを確認しました。

ポイント
  • 20TBのデータをインターネット回線で送るときは、分割して送信
  • 転送処理に時間がかかる。エラーリトライの仕組みも準備
  • スナップショットを取る前には、ディスクキャッシュを吐き出す
  • 分割処理や結合処理に時間がかかる
  • ディスクIOネックの処理には、高性能なディスクを使い、処理時間を節約
  • 移行後のDBの初回実行もチェック処理などでリソースを使うので一時的に高性能なリソースで構築
  • GCPで大きなディスクを作成するとき、時間がかかるとき(~30m程度)や失敗するときがある(時間に余裕を)
  • GCPのWebUIは急に項目が移動したりなくなることがある。(当日焦らないようになるべくコマンドで事前準備したい)

考察

  • この後、1週間でネットワークやアプリ側の移行を行い、差分データをDBサーバに入れて、システム全体の移行を終えました。その後の順調な移行を思うと、やはりこの巨大なDBサーバーが壁だったことを感じます。
  • この頃の多くの企業がそうであったように、E社もデータセンターのレガシーなシステムからクラウドに移行することにより、システムやインフラの変化のスピードが各段に増しました。そして、今や BigQuery, GKE に関してはかなり使い込んでいる部類に入ると思われます。良い決断をしたと思います。
その他
  • 時期:2021年9月~11月ごろ
  • 規模:15名、サーバ20台
  • Google Cloud, MySQL8, Ubuntu 19.10, Ubuntu 20.04LTS