- はじめに
- 作業概要
- 気づいたこと、つまづいた点
- Blue/Greenデプロイの作成には、バイナリログの有効化が必須。
- DBインスタンスの再起動は1分ぐらい。
- Blue/Greenデプロイの作成時にDBエンジンバージョンを変更できる。
- Blue/Greenデプロイの作成は20~25分ぐらい。
- Serverless v2への変更は12~15分ぐらい。
- Blue/Greenデプロイの切り替えは1分から1分30秒ぐらい。
- Blue/Greenデプロイの切り替え後にDBエラーが発生。
- Blue/Greenデプロイで、DB Cluster Identifierベース、DB Identifierベースのメトリクスはそのまま引き継がれる(?)
- binlog_formatがOFFじゃないと、Serverlessは停止しない。
- Sidekiqが起動していると、Serverlessは停止しない。
- DBインスタンスのログを参照すると、停止していたServerlessが起動してしまう。
- ServerlessのFreeableMemoryメトリクスは、インスタンスの実空きメモリ値ではない。
- Serverlessは、スワップ使用量が多い。
- おわりに
はじめに
先日、AWSサーバーの3つのステージング環境で、RDS Aurora MySQL (db.t4g.medium) を、Blue/Greenデプロイ(Blue/Green Deployments)を使用して Serverless v2 に切り替える機会がありました。
切り替えに合わせて、DBエンジンのバージョンアップも実施しました。
AWSのドキュメントやインターネット上の多くの記事で既に書かれているので、詳細の作業手順はここには記載しませんが、気づいたことやつまづいた点などを、メモ書きとして残しておきます。
なお、この作業は、AWS費用削減対応の一環として実施しました。
作業概要
Serverless v2への切り替えの大まかな作業手順は以下となります。
- パラメータbinlog_formatをOFFからRAWに変更してDBインスタンスを再起動
- Blue/Greenデプロイの作成
- GreenでDBインスタンスをServerless v2に変更
- Blue/Greenデプロイで切り替え
- パラメータbinlog_formatをRAWからOFFに変更してDBインスタンスを再起動
- Blue/Greenデプロイの削除と古いBlue DBクラスターの削除
切り替え時のダウンタイムを短縮するため、Blue/Greenデプロイを使用します。
Serverlessについては、費用削減のため、DBを使用しないときは停止するよう、以下を指定しました。
- ACUのキャパシティは、最小 0、最大 4
- 非アクティブ後に一時停止する時間は 5分
5. パラメータbinlog_formatをRAWからOFFに変更してDBインスタンスを再起動
については当初予定していなかった作業です。
これについては後述します。
DB接続ができなくなるダウンタイムが発生するタイミングとしては、1,4,5 の3回ありました。
それぞれ、1分から長くても1分30秒程度です。
この手順は、以下などを参考にしました。
ありがとうございます。
・データベース更新のために Amazon RDS ブルー/グリーンデプロイを使用する – RDSユーザーガイド
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/blue-green-deployments.html
・AWS Amazon RDS Aurora MySQL をブルーグリーンデプロイを使用してAurora Serverless v2に移行する
https://zenn.dev/minedia/articles/88bbea2e70a233
気づいたこと、つまづいた点
今回実施したBlue/GreenデプロイとServerlessに関して、気づいたことやつまづいた点は、以下のとおりです。
- Blue/Greenデプロイの作成には、バイナリログの有効化が必須。
- DBインスタンスの再起動は1分ぐらい。
- Blue/Greenデプロイの作成時にDBエンジンバージョンを変更できる。
- Blue/Greenデプロイの作成は20~25分ぐらい。
- Serverless v2への変更は12~15分ぐらい。
- Blue/Greenデプロイの切り替えは1分から1分30秒ぐらい。
- Blue/Greenデプロイの切り替え後にDBエラーが発生。
- Blue/Greenデプロイで、DB Cluster Identifierベース、DB Identifierベースのメトリクスはそのまま引き継がれる(?)
- binlog_formatがOFFじゃないと、Serverlessは停止しない。
- Sidekiqが起動していると、Serverlessは停止しない。
- DBインスタンスのログを参照すると、停止していたServerlessが起動してしまう。
- ServerlessのFreeableMemoryメトリクスは、インスタンスの実空きメモリ値ではない。
- Serverlessは、スワップ使用量が多い。
Blue/Greenデプロイの作成には、バイナリログの有効化が必須。
BlueからGreenへのデータ同期にMySQLレプリケーションを使用するため、バイナリログの有効化が必須ということですね。
パラメータ binlog_format=RAW
を設定し、反映するためにDBインスタンスを再起動します。
DBインスタンスの再起動は1分ぐらい。
パラメータ反映のための再起動で、ステータスが「利用可能」となるまでは1分ぐらいでした。
ストレージ使用量(VolumeBytesUsed)は、65MBから620MB程度と少なめでしたが、データ量が多いと時間が長くなるかもしれません。
Blue/Greenデプロイの作成時にDBエンジンバージョンを変更できる。
Blue/Greenデプロイで、Greenデータベースを作成する際に指定できる項目は、以下の3つ(のみ)です。
- DBエンジンバージョン
- DBクラスターパラメータグループ
- DBパラメータグループ
もともと、DBエンジンのアップグレード時間を短縮するために用意された機能、ということですね。
これ以外の情報はすべて元のDBクラスター、DBインスタンスの情報を引き継ぎます。
インスタンスタイプの変更や、Serverlessへの変更はできないため、Greenを作成してから切り替える前に、実施することになります。
※非Auroraでは、ストレージタイプやサイズの変更が可能なようです。
・Amazon RDS のブルー/グリーンデプロイでストレージボリュームの縮小をサポート – AWS
https://aws.amazon.com/jp/about-aws/whats-new/2024/11/amazon-rds-blue-green-deployments-storage-volume-shrink/
Blue/Greenデプロイの作成は20~25分ぐらい。
Blue/Greenデプロイを作成には、20~25分ぐらいかかりました。
マネジメントコンソールのイベントを見る限り、このうち、DBエンジンのアップグレードに3~4分ぐらいかかったようです。
Serverless v2への変更は12~15分ぐらい。
インスタンスタイプの db.t4g.medium から Serverless v2 への変更には、12~15分ぐらいかかりました。
Blue/Greenデプロイを使わないと、これぐらい長いダウンタイムが発生することになります。
Blue/Greenデプロイの切り替えは1分から1分30秒ぐらい。
フェイルオーバーより少し長いぐらいでしょうか。
これもデータ量によって違いがありそうです。
Blue/Greenデプロイの切り替え後にDBエラーが発生。
切り替え後に、ECS上で稼働するRailsアプリケーションで以下のようなDBエラーがいくつか発生しました。
Mysql2::Error: The MySQL server is running with the --read-only option so it cannot execute this statement
Blue/Greenデプロイの切り替え時は、AWS側でDNSを書き換えることで接続エンドポイン名を維持するため、アプリケーションからのDB接続先は変更する必要がありません。
しかし、アプリケーション側でDBコネクションプーリングをもつような構成の場合は、アプリケーションは古いインスタンスへのDB接続をキープしてしまうんですね。
ですので、フェイルオーバー時も同様ですが、アプリケーションの再起動(ECSであればタスクの入れ替え)が必要でした。
Blue/Greenデプロイで、DB Cluster Identifierベース、DB Identifierベースのメトリクスはそのまま引き継がれる(?)
すべてのメトリクスを確認したわけではありませんが、CloudWatchダッシュボードやアラームで使用していた、以下のメトリクスは、古いDBクラスター、DBインスタンスのものがそのまま引き継がれました。
- CPUUtilization
- FreeableMemory
- SwapUsage
- VolumeBytesUsed
- ReadLatency, WriteLatency
- DatabaseConnections
- Queries
引き継がれたメトリクスに対してしきい値を設定したCloudWatchアラームも、そのまま使用できる、、はずですが、僕は念のため作成し直しました。
以下は、Serverlessの動作、仕様について。
binlog_formatがOFFじゃないと、Serverlessは停止しない。
Serverlessに切り替えたあと様子を見ていると、メトリクスでは DBConnections がずっと 0 なのに、RDSは停止しませんでした。
Queiesメトリクスを見ると、5/sec ぐらいのクエリが発生しています。
調査したところ、以下の情報を見つけました。
・Aurora Serverless v2の最低ACUを0にしても止まらなかった話 – DELTAテックブログ
https://zenn.dev/team_delta/articles/dd1372fa046af7
バイナリログを出力していると停止しないということで、
パラメータ binlog_format=OFF
として、DBインスタンスを再起動しました。
すると、想定どおり、5,6分程度経過したのち、自動停止しました。
自動停止発生の確認方法としては、DBクラスターの状態が「一時停止」となっていることのほか、以下があります。
- ServerlessDatabaseCapacityメトリクス が 0 となる。
- RDSクラスターの「最近のイベント」で「Successfully paused the DB instance」のようなメッセージが表示される。
ダウンタイムを短くするためにBlue/Greenデプロイを使用するのですが、そのためのパラメータ変更で「1分程度 x 2回」のダウンタイムが余計に発生することになります。
本番環境で実施するときは、この点も考慮する必要がありますね。
なお、自動一時停止のしくみや、自動停止を阻害する要因などは、AWSのユーザーガイドにも解説があり、参考になります。
・Aurora Serverless v2 の自動一時停止と再開によるゼロ ACU へのスケーリング – Auroraのユーザーガイド
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2-auto-pause.html
Sidekiqが起動していると、Serverlessは停止しない。
3つのAWS環境で実施したところ、1つはServerlessが停止したのですが、残り2つは停止しませんでした。
Railsアプリケーション環境の違いとしては、
停止したほうは、Puma のみ起動しており、
停止しなかったほうは、Puma と Sidekiq が起動していました。
Puma と Sidekiq で、アプリケーションのWorkerプロセスや、DBコネクションプールの仕様 and/or 設定の違いがあるようです。
※私はアプリケーション担当ではないので細かい仕様は把握しておらず、またアプリケーション設定は確認していません。
DBインスタンスのログを参照すると、停止していたServerlessが起動してしまう。
マネジメントコンソールのサービスRDSの画面で、DBインスタンスのログを表示すると、停止していたServerlessが起動します。
一方、DBクラスターのログを表示したときは、停止したままです。
この仕様は事前に以下の記事を目にしていて、実際にそのとおり動作することを確認できました。
・Aurora Serverless v2はACU 0に設定してもログを確認すると起動します – Developers.IO
https://dev.classmethod.jp/articles/aurora-serverless-v2-acu-0-but-awake/
DBインスタンスのログは、サービスRDSの画面ではなく、CloudWatch Logsの画面で確認するよう注意します。
ServerlessのFreeableMemoryメトリクスは、インスタンスの実空きメモリ値ではない。
FreeableMemory メトリクスを確認すると、約7GBとなっていました。
↑赤で囲ったあたりが、Serverlessへの切り替えタイミング。
「ACUはほぼ0.5(メモリ1GiB相当)で推移しているのに不思議だな、実はServerlessはたくさんメモリを確保しているのかな?」
と思いましたが、そんなことはありません。
AWSの仕様では、Serverlessの FreeableMemory メトリクスは、以下を意味するとのことです。
FreeableMemory。この値は、Aurora Serverless v2 DB インスタンスを最大容量にスケーリングしたときに利用できる未使用のメモリ量を表します。
Aurora Serverless v2 でのパフォーマンスとスケーリング – Auroraのユーザーガイドより
今回は最大容量 4ACU(メモリ8GiB相当)としており、「8GiBにスケーリングしたときに約7GiBの空き」ということは、「約1GiB使用している」ことを意味するのでしょう。
これなら、FreeableMemory ではなく、MemoryUsed メトリクスがほしい。。
Serverlessは、スワップ使用量が多い。
今回Serverlessに移行したデータベースは、ほとんどDB接続がなく、起動している間のACUはほぼ 0.5 で推移しています。
↑赤で囲ったあたりが、Serverlessへの切り替えタイミング。
メモリ1GiBではさすがに足りないようで、Serverlessへの切り替え前よりスワップ使用量が増えました。
なお、このサーバーのストレージ使用量(VolumeBytesUsedメトリクス)は、620MB程度です。
他のDBエンジンはわかりませんが、LinuxサーバーにMySQLサーバーをインストールした場合でも、
「MySQLは空きメモリがあってもスワップをけっこう使う」
という印象があり、Serverless(の最小容量)で搭載メモリが減ると、さらにスワップ使用量が増えるのは納得です。
と考えると、MySQLのスワップ使用によるレスポンス性能劣化は少し心配です。
ステージング環境ではまだよいのですが、本番環境で、低容量で使用するかどうかは慎重に検討する必要があります。
おわりに
AWSで、RDS Aurora MySQL (db.t4g.medium) を、Blue/Greenデプロイを使用して Serverless v2 に切り替えたときに、気づいたことやつまづいた点などを、まとめました。
Blue/Greenデプロイも、Serverlessも、とても便利な機能ですが、やってみないとわからなかったことも多く、やはり検証は大事だと思いました。
今回はステージング環境で実施しましたが、1ヶ月ほど様子を見て、本番環境にも同様に実施するかどうか、検討します。
本番環境では、Serverlessにはせず、DBエンジンのアップデートのみ実施するかもしれません。
AWS費用削減対応の一環としては、他に以下も実施しました。
- ECSタスクのタスクサイズを小さく。
- ElastiCache for RedisをValkeyに変更。
- 管理、調査用のEC2インスタンスを停止し、必要なときのみ起動するよう運用を変更。
どれくらい費用削減効果があったか、楽しみです。





