なぜオンプレミスのデータベースをクラウドに移行するのか
データベースをクラウドに移行する理由は大きく分けると以下の4つです。
- (1) データセンター移設の決定
- (2) ポイントサービス全体をクラウドに移行するための布石
- (3) データベースのストレージを気にしたくない
- (4) 見えにくいコストの見える化
以前よりポイントサービス全体をクラウドに移行する計画を立てていましたが、オンプレミスのデータベースが稼働しているデータセンターの利用停止が決まったため、早急にクラウド移行を行うことを決定しました。
データセンター撤退までの期日が決まっているため、整合性を担保しつつ、"なるべく早くクラウド移行を完了させる"ことを優先しました。
クラウド移行を行う理由について一つずつ解説していきます。
(1) データセンター移設の決定
オンプレミスのデータベースが稼働しているデータセンターを2021年6月中に他の場所に移設することになりました。
クラウド化を行わない場合、オンプレミスで稼働していた物理サーバーを別のデータセンターに運んで設置する、または、新しく作成する必要があります。いずれも、非常に大きな費用がかかるため、これを避けたいと考えました。
(2) ポイントサービス全体をクラウドに移行するための布石
現在、ポイントサービスの8割はオンプレミスのサーバーで稼働しています。
DeveloperExperienceの向上、開発サイクルの高速化、オートスケールなどの目的のため、ポイントサービス全体をクラウドに移行し、モノリシックなシステムを適切な単位に分割していく計画を立てています。
オンプレミスからクラウドに移行するにあたり、一番ボトルネックになるのがデータベースの移行であると考えました。
データベースのクラウド移行がボトルネックになる要因
- 1つのデータベースを複数のアプリケーションから使用しているので、影響範囲が広い。
- 完全にサービスに影響を与えない状態での切り替えが難しい(一時的にサービスを利用できない時間が発生する)。
- 数TBのストレージを使用しているのでデータ移行に時間がかかる。
このように面倒ごとの多いデータベースのクラウド移行をアプリケーションより先に実施することで、サービス全体のクラウド移行のボトルネックを取り除き、クラウド移行を加速しようと考えました。
(3) データベースのストレージを気にしたくない
現在のポイントサービスでは、履歴情報などの増え続ける情報をリレーショナルデータベースに保存しています。
それによりストレージの使用容量が上がり続け、いずれパンクすることが分かっていました。
最終的には履歴情報をリレーショナルデータベースとは別の方法で管理することを予定していますが、その対応を実施するまで空きストレージを意識したくないと考えました。
Amazon Auroraを使用することで、128TBまでストレージを自動拡張できます。
(4) 見えにくいコストの見える化
オンプレミスの場合、DBを載せているマシンの費用だけでなく、そのマシンを配置しているデータセンターでの管理費やインフラチームの運用費など、見えにくいコストが多く存在します。
クラウドへ移行することで、コンソール上で利用サービス毎の料金を確認できるようになり、システムの利用傾向からリザーブドインスタンスによってコストを節約したりする選択肢も生まれてきます。
これらの恩恵を受けるため、クラウドへ移行したいという想いもありました。
オンプレミスからクラウドへデータベースを移行する方法
次に、クラウドへデータベースを移行する具体的な方法について解説します。
私たちの場合は複数の移行方法について提案・検討を行い、移行方法を決定しました。
まずはボツ案から簡単にイメージ図で紹介します。
-
オンプレミスからクラウド、クラウドからオンプレミスに双方向でレプリケーションをする方式(双方向レプリケーション方式)
- アプリケーションからオンプレミス、クラウドの両方のデータベースに書き込みを行う方式(ダブルライト方式)
これらの方式はいずれもアプリケーションのダウンタイムを発生させずに移行できる方式ではありますが、整合性を担保しつつクラウドに移行するには期間が足りないと判断しました。
最終的にはポイントサービスを一時的にメンテナンスモードにして利用できなくし、その間にクラウドへ移行するシンプルな方式を採用しました。
最終的な移行方式は下記のイメージ図のようになります。
最終的な移行方式について、順を追って説明します。
Amazon Auroraの構築
オンプレミスではMySQL 5.6を使用していたので、Amazon Aurora MySQL互換を使用してクラウドにデータベースを作成しました(MySQL互換バージョンは5.7を使用)。
オンプレミスからAmazon Auroraへのデータ移行はmysqldumpとレプリケーションを使用して行いました。
移行データは約3TBあるため、一時的にインスタンスタイプを最もスペックの高いもの(db.r5.24xlarge)に変更することでリストア時間の短縮を図りました。
また、データリストア後にindexを追加することでindexの計算時間を減らす工夫をし、最終的には約7日間でデータのリストアを完了できました。
データリストア後にオンプレミスからAmazon Auroraへレプリケーションを行い、約2日間でレプリケーションが追いつきました。
データリストア時は一時的にインスタンスタイプを db.r5.24xlarge にしていましたが、コストが高いので今後運用するのに適したインスタンスタイプを決定する必要がありました。
インスタンスタイプを決めるために、本番環境用のデータベースをクローンして負荷試験を実施しました。
Amazon Auroraはクローンをボタン一つで簡単に作成できるため、容易に試験を行うことができます。
負荷試験の結果を検証し、インスタンスタイプを決定しました。
これでAmazon Aurora側の準備が整いました。
アプリケーションの接続先をAmazon Auroraへ切り替え
メンテナンス時間を最小限にするために、メンテナンス実施前にデータベースの参照のみを行うアプリケーションの接続先の切り替えを実施しました。
Amazon Aurora側には常に最新データがレプリケーションされているので、参照先の切り替えは容易に行うことができました。
その後、一時的にサービスをメンテナンスモードにし、データ更新を行うアプリケーションの接続先をAmazon Auroraへ切り替えました。
動作確認を行って、問題がないことを確認した後に、オンプレミスのデータベースからAmazon Auroraへのレプリケーションを停止することでクラウド移行を完了させることができました。
事前に準備していたこともあり、メンテナンス時間は2時間程度で完了できました。
下記の図は、実際のデータベースの構成になります。
オンプレミスDBのクラウド移行で苦労したこと
前述の方法で無事オンプレDBをクラウドへ移行できましたが、その途中、様々な苦労もありました。
ここでは、その苦労話をいくつか紹介します。
- オンプレミスDBの経緯不明のMySQLサーバーパラメータをAmazon Auroraへ反映
- オンプレサーバからDBまでの距離が遠くなったことにより想定外にバッチ処理時間が伸びた
- マシンスペックに頼っていたクエリの修正
- MySQLバージョンの差異によって応答のないクエリがあった
オンプレミスDBの経緯不明のMySQLサーバーパラメータをAmazon Auroraへ反映
長年運用されてきたオンプレミスDBのMySQLサーバーパラメータは、他のDBからのコピーによる引き継ぎや多くの参照先の要望に応えてきたことで、経緯不明のパラメータが多数設定されていました。
私たちはクラウド移行時に問題が発生するリスクを抑えるため、できる限りオンプレミスDBのサーバーパラメータをそのままAmazon Auroraへ引き継ぐことを目指しました。
まず、オンプレミスDBのサーバーパラメータとAmazon Auroraのデフォルトで設定されているサーバーパラメータを比較し、設定値が異なるパラメータを洗い出しました。
そして、設定値の異なるパラメータの詳細を調べ、設定値を変更する必要があるかを判断していきました。
結果的には引き継ぐ必要のあるパラメータはそこまで多くはないことが分かり、max_allowed_packet、character_set_databaseなどの文字コード関連、collation_serverなどの照合順序関連のパラメータを設定しました。
オンプレサーバからDBまでの距離が遠くなったことにより想定外にバッチ処理時間が伸びた
参照先をオンプレミスDBからクラウドDBに切り替えたことによって、バッチの処理時間が1.5時間から5時間に伸びたものがありました。
原因を調査したところ、バッチの中でデータを1件だけ取得するような軽量なクエリが大量に発行されており、それがボトルネックになっていることが分かりました。
元々同じデータセンターにあったバッチサーバーとDBサーバーでしたが、DBサーバーをクラウドに移行したことにより、単純に距離が遠くなったことで通信にかかる時間が伸びました。
例えば、通信の往復にかかる時間が5msしか伸びなかったとしても、100万回クエリが発行されると83分間もかかることになります。
このように大量のクエリを発行しているバッチは、まとめて処理するようにロジックを修正したり、キャッシュを使えそうなところはキャッシュしたり工夫する必要がありました。
マシンスペックに頼っていたクエリの修正
移行前のオンプレミスDBはCPU48コア、メモリ192GBのモンスタースペックのマシンを3台使っていました。
このスペックをクラウドに移行しようとすると凄まじい料金がかかってしまいます。
アプリケーションの向き先をクラウドDBに変更した状態で負荷試験を行ったり、バッチを実行したりすることでAmazon Auroraの必要スペックを計算し、結果的には db.r5.4xlarge のインスタンスクラスを利用することに決定しました。
単純にオンプレミスDBの時よりもスペックを落としたことで、クエリの実行時間が全体的に伸びましたが、そのなかでも応答がなくなったクエリもありました。
応答がなくなったクエリは軒並みインデックスが効いていないクエリだったため、インデックスが効くようにクエリを修正することで解決できました。
MySQLバージョンの差異によって応答がないクエリがあった
Amazon AuroraにMySQL 5.7互換機能があったため、クラウド移行時にオンプレミスのMySQL 5.6からAmazon AuroraのMySQL 5.7にバージョンアップも同時に行いました。
しかし、検証中に応答のないクエリが見つかり、インデックスが効かずにテーブルをフルスキャンしていることが分かりました。
結論としては、MySQL 5.7で新規に追加されたMySQLサーバーパラメータのrange_optimizer_max_mem_sizeが原因でした。
SQLのIN句に大量の条件が指定されているクエリが、range_optimizer_max_mem_sizeの制限によってフルスキャンになってしまっていました。
私たちと同じ状況に陥らないように、これからクラウド移行をする方々は、問題を切り分け易くするためMySQLのバージョンを合わせることをオススメします。
まとめ
今回の記事ではデータベースをオンプレミスからクラウドに移行するまでの経緯、具体的な移行方法、苦労した点について紹介しました。
データベースの移行が完了したので、アプリケーションのクラウド移行も引き続き実施していく予定です。
繰り返しになりますが、今回の内容がデータベースのクラウド移行を考えている方や、具体的な移行方法を考えている方の参考になれば幸いです。