はじめに
こんにちは。GiftmallのEC機能の開発やインフラの運用を担当している藤原(@fujishochan)と申します。本年の1月、Aurora MySQL V1のEOLを受けて、GiftmallのProduction環境の一部で使っていたAurora MySQL V1のDBをAWS RDS Blue/Green Deployment (以下、RDS Blue/Green Deployment)を用いてAurora MySQL V2に移行しました。今回、その移行プロジェクトの内容を紹介します。本記事がRDS Blue/Green Deploymentを使われる方の参考になればと思うと同時に、エンジニアリングが主導して行うプロジェクトの進め方の一つの例としても参考になればとも考えております。
背景
対象システムのDB構成
DB移行対象のシステムの概略を以下の図に示します。
図を説明しますと、ALBでロードバランシングを行い、アプリケーションはEC2でホストし、DBはAurora MySQL で運用する構成となっています。DB周りにフォーカスしますと、アプリケーションはDBクラスタのWriterに接続し、RDS Proxy経由でETLツールやBIツールをReaderに接続して運用しております。今回、この図の中のProduction DB clusterをAurora MySQL V2に移行しました。
AWS RDS Blue/Green Deployment を採用するに至るまでの経緯
リスク整理とその対処方針の決定
2023年1月の移行完了を目標に、2022年11月後半よりDBの移行プロジェクトを開始しました。
はじめに、DBの非互換性によって発生しうるリスクの整理を行いました。
- Aurora MySQL V1とAurora MySQL V2は、ベースとなるMySQLのバージョンの違いに起因する一部のIN句を条件に含むクエリ実行計画の違いが発生しうることを認識しており、移行のタイミングで特定のクエリが遅くなることによってサイトが表示できなくなるといった問題が発生するリスクがありました。
- 我々のアプリケーションが発行しているクエリの特性(IDやUnique Key等を使った更新)から更新系のクエリの挙動が変化する可能性はかなり低いと見込んでいましたが、更新系のクエリの結果が変わってしまうというリスクも排除しきれないと考えました。万が一それが起きてしまった場合の対処方針を明確にしておくことがプロジェクトをコントロールするために重要と考えました。
- 対象のシステムに関しては、弊社でコントロールができない外部システムとの連携があり、移行後のDBで対象システムの運用が開始した後のロールバックは現実的に難しいと判断しました。
これを踏まえて、移行によって発生するリスクの対応方針を定めました:
- 移行完了後はよほどのことがない限りロールバックという選択肢がないということを念頭に置いて、できるかぎり事前の確認を手厚く行う。データの不整合特に注文機能等で不整合が発生すると致命的になるため、その箇所を念入りに行う。代わりに、Select系のクエリでパフォーマンスの問題が出ることはある程度許容する。
- DB移行後に発生する問題をできるだけ早いタイミングでキャッチ・対応するために、移行作業と移行後の運用初期段階においては手厚いフォローができるように移行作業前後の人員計画を立てる。
In-Place Update vs Blue/Green Deployment
プロジェクト開始当初はRDS Blue/Green Deploymentは存在しておらず、Aurora ClusterのIn-Place Updateあるいはこちらの記事にあるようなマニュアル作業でのBlue/Green Deploymentのいずれかの方法でのDB移行を検討しました。この両者のどちらを選んでもDB移行後のリスク対応の方針は同じとなりますが、In-Place Updateと比較してダウンタイムを小さくできることや、旧バージョンのDBが残るために移行の途中で問題が発生した場合はロールバックがしやすいといった利点を持つBlue/Green Deploymentを採用することで方針を決定し、調査・検証作業に入りました。
RDS Blue/Green Deploymentのリリースによる状況の変化
そんな中で、2022年11月27日のRDS Blue/Green Deploymentのリリースは私たちにとっては非常に良いニュースでした。(個人的な所感ですが、こちらは、弊社のようにAurora MySQL V1を使用している利用者に向けて「早く移行をしてください」というAWSのメッセージも含んでいたようにも受け取れました。) リリース直後、情報を確認した限りでは、対象システムのようにRDS Proxyが存在する構成に対応しているかどうか等不透明なところがあったのですが、手作業でのBlue/Green Deploymentと比較して作業がシンプルとなり、かつ切り替えの自動化によってダウンタイムがより短くなるという見込みがあったので、RDS Blue/Green Deploymentを採用することを意思決定しました。
RDS Blue/Green Deploymentの調査・動作検証
一般に、DBのメジャーバージョンアップを行う場合、新しいバージョンのDBでアプリケーションが動くかどうかを機能的・非機能的側面から確認する作業を実施することと思います。このプロジェクトでは、そういった一般的な検証のほか、RDS Blue/Green Deployment自体の調査・動作検証も行いました。
RDS Blue/Green Deploymentを採用することにしたものの、ローンチされたばかりのサービスであり、事例もないため、カタログスペックやマニュアルを参考にすることはもちろんですが、それに加えて動作検証を少し詳細に行うことにしました。(もしこの検証の結果が芳しくなかった場合は別の方法でDBの移行を行う予定でしたが、少なくとも我々のユースケースに関しては問題はなく、このまま移行を進めることにしました)
動作検証の内容
構成的には以下のパターンの動作検証を行いました
- Writerのみを持つクラスタ
- WriterとReaderを持つクラスタ
- WriterとReaderと、かつそれらを参照しているRDS Proxyが存在するクラスタ (Production DBと同じ構成)
その他、以下のような観点の検証を行いました
- Green環境に対して直接DBの更新を行なった際に何が起きるか
- Switch Over前のDeploymentの削除がどのような動きをするか
- Switch Over後のDeploymentの削除がどのような動きをするか
- Blue環境にRDS Proxyを向けた状態でのSwitch Overがどのような動きをするか
- Green環境にRDS Proxyを向けた状態でのSwitch Overがどのような動きをするか
- Blue環境がAudit Logを使用している場合にAWS Blue/Green DeploymentにおいてAudit Logがどのような動きをするか
動作検証の結果
動作検証の結果としては、RDS Blue/Green Deploymentを使って問題なく移行できそうだという結論になりました。この動作検証においていくつかTIPsとして共有する価値がありそうな知見をここでは紹介いたします。
なお、ここで紹介する知見は、Aurora MySQL V1クラスタのBlue環境からAurora MySQL V2クラスタのGreen環境へのRDS Blue/Green Deploymentを作成・操作した際の挙動に関するものです。Blue環境/Green環境の違いやAWS内部のアップデートによって必ずしも再現はしないかもしれません。
Green環境作成直後のパラメータグループ
Green環境を作成した直後、クラスタの各インスタンスを再起動するまで、適用されるパラメータはGreen環境作成時に指定したパラメータグループでなく、Green環境で使うエンジンのデフォルトになっていました。そのため、Green環境作成後は、Green環境のクラスタを再起動する必要がありました。
Green環境に対して直接DBの更新を行なった場合の挙動
Aurora MySQLのRDS Blue/Green DeploymentにおけるBlue環境とGreen環境の同期はMySQLネイティブのReplicationを使用していました。(公式でもこちらのページで説明されていますが )Green環境は読み込み専用にはなっていないので、直接DBの更新を行うことができました。意図せずGreen環境に対して更新を行なってしまわないように注意する必要があります。
RDS Proxyが存在する構成の挙動
公式のドキュメントにRDS Blue/Green DeploymentではRDS Proxyをサポートしていないということが書かれていますが、実際にRDS Proxyが存在する状況でRDS Blue/Green Deploymentを使おうとした場合に何が起きるのかを確認しました。
主な確認結果は以下のとおりです(2022年12月に確認を実施しています)
- RDS Proxyが存在するDeploymentは作成することができませんでした。
- (*) Blue環境を参照しているRDS Proxyが存在している状況でSwitch Overができることを確認しました
- Green環境を参照しているRDS Proxyが存在している状況でSwitch Overができることを確認しました
なお、(*) については、当初、こちらを前提とした手順を組んでおりましたが、後述のリハーサル段階でBlue環境を参照しているRDS Proxyが存在する場合にSwitch Overが失敗するようになっており、手順を調整したという経緯があります。このように、検証段階で動いていたことがある日アナウンスなく動かなくなることもあるので、特にクラウド上でのインフラの作業に関しては本番から近いタイミングでのリハーサルを行うことは大事と思います。
Switch Overにかかる時間
Production DBと同じ構成(RDS Proxy 1台およびReader/Writerインスタンスを持つ)でかつ同じ規模のデータセットを持つAurora Cluster(ただし、インスタンススペックは低い)を用意してBlue Green DeploymentによるSwitch Overを行った結果の所要時間は4分でした。この4分という数字はAWS Consoleで確認できるDeploymentのログによるもので、実際にAuroraのエンドポイントの参照先が切り替わるまでの時間はこれと前後することはあるかもしれません。より確信度の高い数字を出すためには、何度もSwitch Overを試して処理時間を出すと確実と思いますが、今回はそういった作業をするほどのリスクはないと判断しました。
Audit Logを使用している場合の挙動
AWSのドキュメントで紹介されているAudit Logを使う場合、その設定はパラメータグループで設定を行いますが、上で述べたように、Green環境のパラメータグループの適用はクラスタの再起動が必要となりますので、Green環境作成後はクラスタの再起動を必ず行う必要があります。ログの送信設定については、Blue環境の設定がコピーされる挙動となっていました。
また、Audit LogをCloudWatch Logsに送信している場合、Green環境のログは、SwitchOver前はGreen環境固有のロググループに送信されます。クラスタの名前が変わる影響で、SwitchOver後はGreen環境のログはSwitchOver前のBlue環境のロググループに、Blue環境のロググループはDeploymentでrenameされた固有のロググループに送信されます。
Switch Over前のDeployment削除
DeploymentをSwitch Over前に削除した場合、Green環境が消え、Blue環境がDeployment作成前の状況に戻ることを確認しました。
移行作業
調査・動作検証の結果を踏まえ、実際の移行作業の手順を作成・実施しました。
その内容を以下に紹介します。
1. DB切り替え前の事前準備
ダウンタイムを伴うこともあり、DB切り替え作業時の作業内容をできるだけ少なくするために、事前準備を行います。今回、この作業は実際の切り替え作業予定日より1週間前に実施しました。(対象システムの規模であれば一週間前であれば十分余裕があると判断しました)
現行のAuroraクラスタのbin logを有効にする
Aurora MySQLのRDS Blue/Green DeploymentではMySQLネイティブのレプリケーションを使用するので、Blue環境となる現行のAuroraクラスタのbin logをあらかじめ有効にしておきます。この際、クラスタの再起動が必要となります。(つまりダウンタイムが発生します)
Green環境のパラメータグループを用意する
Deployment作成時にGreen環境でパラメータグループを指定する必要があるため、あらかじめGreen環境用のパラメータグループを作成しておきます。
Deploymentを作成する
実際の切り替えで使うDeploymentを作成します。Blue環境となるAuroraクラスタを参照しているRDS Proxyが存在するとDeploymentを作成できないため、Deployment作成にあたっては当該Auroraクラスタを参照しているRDS ProxyのターゲットグループからそのAuroraクラスタを削除します(つまりRDS Proxyが一時的に利用できなくなります)。Deploymentを作成したらRDS Proxyターゲットグループを元に戻します。さらに、Green環境となるAuroraクラスタを再起動してパラメータグループが確実に適用されるようにします。
なお、RDS ProxyのターゲットグループからAuroraクラスタを削除することはAWS Management Consoleからはできず、以下のAPIを呼ぶ必要があります:
APIを呼ぶようにしてもよいのですが、AWS Supportに問い合わせたところ、RDS Proxyのターゲットグループを全く別のDBインスタンスに入れ替えることで、ターゲットグループからの削除にかえることができることを確認しました。今回の移行は基本的にAWS Management Consoleを使って作業する予定であったため、AWS Management Consoleを使って作業ができる「RDS Proxyからのターゲットグループを全く別のDBインスタンスに入れ替える」方法を今回は採用することにしました。
Green環境の動作確認をする
作成したGreen環境が期待通りに動作しているかを確認します。今回は、以下の点を確認しました。
- パラメータグループが実際に適用されていること
- レプリケーションがされていること
今回は、パラメータグループが適用されていることの確認として、show variables
クエリの結果確認の他、Green環境に対してAudit Logの取得対象となるクエリの実行を行い、Audit Logが意図通り送信されていることを確認することでパラメータグループの適用確認としました。
レプリケーションの動作については、Blue環境に対して show master status
、Green環境に対して show slave status
を何度か実行してレプリケーションが進んでいることを確認することで動作確認としました。
事前準備後のDB構成
事前準備が完了した段階で、対象システムのDB構成は以下の通りになっています。
2. DB切り替え作業
事前準備の後に、DeploymentのSwitch Overによって運用するDBを切り替えました。
切り替え作業の内容を以下に紹介します。
レプリケーション遅延が発生していないことを確認
SwitchOverではBlue環境への更新をGreen環境に反映仕切ってからDBの切り替えを行うため、両環境間でのレプリケーション遅延があると、その分長く時間がかかってしまう(=ダウンタイムが長くなってしまう)ことになります。ダウンタイムを可能な限り短くするために、このタイミングでBlue環境とGreen環境間のレプリケーションを遅延を改めて確認しました。
レプリケーション遅延が発生していないことについては、Blue環境に対して show master status
、Green環境に対して show slave status
を何度か実行してBinlogのポジションがお互いに近いことやレプリケーションが進行していることで確認をしました。
なお、今回は事前準備完了からDB切り替え作業日まで一週間の時間があったため、念の為同様の確認をDB切り替え作業日までの間に途中何度か実施しています。
システムをメンテナンス状態に切り替える
Switch Overを行うにあたって、システムをメンテナンス状態に切り替えてアプリケーション(Web、Batch)がDBに接続していない状態を作ります。(ここでダウンタイム開始となります)さらに、Deploymentを作成したときと同様に、Blue環境を参照しているRDS Proxyが存在しないようにします。(この段階では、RDS ProxyをGreen環境に向けることはせず、Blue環境/Green環境共に参照しているRDS Proxyが存在しないようにします)
DeploymentのSwitch Overを実施する
AWS Management ConsoleよりSwitch Overを実施します。
以下の通り、SwitchOverは検証時と同じ4分で完了しました。(Blue環境の停止は手動です)
アプリケーションが新DBに接続をしていることを確認する
RDS Blue/Green DeploymentによるSwitch Overでは、対象のエンドポイントの接続先がBlue環境からGreen環境に変わる仕組みとなっているため、アプリケーション側の設定を変更せずにDBの切り替えを行うことになります。
そのため、アプリケーションが新DBに接続することを確認するためには、アプリケーションが使うDBエンドポイントがGreen環境に接続していることを確認します。今回はMySQL Clientを使って接続を行った時に表示されるバージョン情報を確認することで、Green環境への接続ができたと判断しています。
さらに、Audit Logの送信テストとして、アプリケーションが使うDBエンドポイント経由でテスト用のSQLを発行し、それがCloudWatch Logsに記録されていることも確認しました。
また、RDS Proxyについても元々Blue環境に接続していた対象のエンドポイントを再度TargetGroupに接続し、同様にRDS Proxy経由の接続がGreen環境に向かっていることを確認しました。
システムのメンテナンスを終了する
アプリケーションが新DBに接続した状態で動作することを確認するために、まずはテストのバッチコマンドを実行し、動作が問題ないことを確認した上で、ダウンタイム中に実行を予定していたバッチを実行開始しました。バッチがエラーとならずに実行されていることを確認して、Webのメンテナンスを終了し、サイトを稼働状態に戻しました。その上で、実際にエンジニアがサイトを触ってみてエラー等が発生していないことを確認して、メンテナンスの終了としました。
DB切り替え作業後のDB構成
DB切り替え作業後のDB構成は以下の通りです。(Blue環境はもはや使われないので手動停止し、後日の後始末で消すことにします)
3. DB切り替え後の後始末
DB切り替え後のシステムをしばらく(今回は一日)運用し、動作に問題がないことを確認し、停止したBlue環境を削除します。一方で、万が一問題が発生した際の解析のためにBlue環境のスナップショットについてはしばらく(切り替えから1ヶ月以上)保存しておきます。なお、課金されませんがDeploymentもSwitch Over後は不要なのでタイミングを決めて削除します。
移行作業に関する補足
DB切り替え作業前のリハーサル
今回のDBの切り替え作業にあたっては、予想外のことが起きてダウンタイムが長期化するリスクを最小化したいと考えました。そのため、「2. DB切り替え作業」実施の前日に作業のリハーサルを行いました。
リハーサルを通じ、以下のような問題を見つけ、作業内容・手順の調整を行いました:
- 検証時と異なり、Blue環境を参照しているRDS Proxyが存在する場合にSwitch Overが失敗するようになっていた
- 作業の証跡の記録方法・内容が明確でなかった
- Switch Over後のテスト接続用のコマンドを用意しておらずGreen環境と間違ってBlue環境に接続して確認をしてしまった
- Switch Over後に実行するテスト用SQLの内容が検証しにくいものであった
- Switch Over後のBlue環境の扱いが明確でなかった
実際の切り替え手順書では、移行作業を中止するといった基準などを定めて想定外のことが発生した場合の準備もしていましたが、本番1日前のリハーサルを経たことで、実際のDB切り替え作業に安心感を持って臨むことができ、スムーズな作業に繋げることができました。
移行作業後の振り返り
今回のプロジェクトで得た知見を言語化して組織に還元し、将来に活かすために、移行作業後に関係者で集まってプロジェクトの振り返りを行いました。
振り返りでは様々な意見が出ましたが、本記事の内容(RDS Blue/Green Deployment)に関係する知見としては、以下のようなものがありました:
- RDS Blue/Green Deploymentのカタログスペックをそのまま信用せずに念入りに動作確認したり、リハーサルを入れたことで、自信を持ってDB移行作業を行うことができた。
- AWS上の新しいサービスを導入するにあたってAWSの有料サポートはとても有用であった。実際、RDS Blue/Green Deploymentについては採用を決めてから実際にProduction環境で使うまでの2ヶ月でサービスが突然利用できなくなったり挙動が変わったりすることがあったが、その対処においてAWS側でしかできない解析や情報共有をしてもらえることは大いに役立った。
まとめ
この記事では、RDS Blue/Green DeploymentをProduction環境のDBに対して使った事例として、GiftmallのProduction環境を構成するシステムのDBバージョン更新プロジェクトの内容を紹介しました。RDS Blue/Green Deploymentを使うことで、MySQLネイティブのReplicationを直接設定・操作することなくBlue/Green DeploymentによるDB切り替えが実現できます。その一方で、これをProduction環境に適用するにあたっては自信を持って状況をコントロールしつつ適用ができるように事前の検証やリハーサルといった「自分の手を動かして確認してみる」という手順を踏んでいく必要がありました。(これは、RDS Blue/Green Deploymentに限らずProduction環境に何か新しい技術・サービスを適用する際には共通するスタンスと考えております)
ギフトモールでは、一緒に働く仲間を募集しています!
まずは一度話してみるだけなどのカジュアル面談も歓迎ですので、少しでも興味を持った方はお気軽に連絡ください!