AWS RDS Blue/Greenデプロイを使用したAurora Serverless v2への切り替えの備忘録

はじめに

先日、AWSサーバーの3つのステージング環境で、RDS Aurora MySQL (db.t4g.medium) を、Blue/Greenデプロイ(Blue/Green Deployments)を使用して Serverless v2 に切り替える機会がありました。
切り替えに合わせて、DBエンジンのバージョンアップも実施しました。

AWSのドキュメントやインターネット上の多くの記事で既に書かれているので、詳細の作業手順はここには記載しませんが、気づいたことやつまづいた点などを、メモ書きとして残しておきます。

なお、この作業は、AWS費用削減対応の一環として実施しました。

作業概要

Serverless v2への切り替えの大まかな作業手順は以下となります。

  1. パラメータbinlog_formatをOFFからRAWに変更してDBインスタンスを再起動
  2. Blue/Greenデプロイの作成
  3. GreenでDBインスタンスをServerless v2に変更
  4. Blue/Greenデプロイで切り替え
  5. パラメータbinlog_formatをRAWからOFFに変更してDBインスタンスを再起動
  6. 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インスタンスを停止し、必要なときのみ起動するよう運用を変更。

どれくらい費用削減効果があったか、楽しみです。

タイトルとURLをコピーしました