はじめに
2022年のAWS re:Invent
にて発表となったRDS
でのBlue/Greenデプロイが、すぐにでも導入したい内容だったので、実験がてら検証してみたいと思います。
以下公式の発表と参考サイト
- Announcing Amazon RDS Blue/Green Deployments for safer, simpler, and faster updates
- New – Fully Managed Blue/Green Deployments in Amazon Aurora and Amazon RDS
- Using Amazon RDS Blue/Green Deployments for database updates
- 【衝撃】AWSのRDSがデータを失わないBlue/Greenデプロイに対応しました #reinvent
今回の発表について
今回、新機能として紹介されましたが、2021年8月に以下の記事が公開されている通り、以前から同様のソリューションは実現可能だったようです。
今回のアップデートでマネジメントコンソール上から数ステップでBlue/Greenデプロイの構成が実現できるようになったことが今回新機能として紹介された理由とのこと。
また、以下の制限事項があるため、制限事項に当てはまる場合は残念ながら使用できません。
-
Blue/Greenデプロイ未サポート機能
- Amazon RDSプロキシ
- カスケードリードレプリカ
- クロスリージョンリードレプリカ
- Multi-AZ DB Cluster
- AWS CloudFormation
-
Blue/Greenデプロイ制限事項
- 暗号化されていないDBインスタンスから暗号化されたDBインスタンスへの変更不可
- 暗号化されたDBインスタンスから暗号化されていないDBインスタンスへの変更不可
- Blue環境のDBインスタンスより低いエンジンバージョンへの変更不可
- Blue環境とGreen環境のリソースは同一AWSアカウント
AuroraでのBlue/Greenデプロイ構成構築
1から説明すると長くなるので、今回は東京リージョンでVPC等の準備は完了している前提で進めます。
事前準備
事前準備で紹介する以下2つの手順ですが、後述するAurora
の設定で「EC2コンピューティングリソースに接続」を選択する場合は実施不要です。
後述する手順では 検証で使うEC2インスタンスと接続するために「EC2コンピューティングリソースに接続」の手順で紹介していますが、「EC2コンピューティングリソースに接続しない」を選択する場合は適宜読み替えてください。
VPCサブネットの作成
もしVPC
のサブネットの設定で、3つのAvailability Zone
(以下AZ)が作られていない場合は、以下の例のように3つ準備しておきます。
IPv4 CIDR | Availability Zone |
---|---|
10.1.0.0/24 | ap-northeast-1a |
10.1.1.0/24 | ap-northeast-1c |
10.1.2.0/24 | ap-northeast-1d |
サブネットグループの作成
3AZ
のサブネットグループが作成されていない場合はRDS
のダッシュボードの「サブネットグループ」より作成しておきます。
項目 | 設定 |
---|---|
名前 | 任意(今回はblue-green-subnet ) |
説明 | 任意(今回はblue-green-subnet ) |
VPC | Auroraを所属させるVPC |
アベイラビリティーゾーン | ap-northeast-1a ap-northeast-1c ap-northeast-1d |
パラメータグループの作成
RDS/Aurora
のBlue/Greenデプロイを実施するためにはDBクラスタ用のパラメータグループのbinlog_format
をMIXED
に変更する必要があります。
binlog_format
のデフォルトはOFF
なので、Aurora
作成時に差し替えられるよう前もってbinlog_format
をMIXED
に変更したパラメータグループを作成しておきます。
尚、デフォルトのパラメータグループはパラメータの変更ができないため新規で作成してパラメータ変更を行う必要があります。
今回の場合、DBクラスタ用のパラメータグループにしかbinlog_format
のパラメータが存在しないため、DBインスタンス用のパラメータグループは新たに作成する必要はありませんが、前述の通り、デフォルトのパラメータグループはパラメータ変更ができないため、ついでにDBインスタンス用のパラメータグループも今後を考えて作成しておきます。
以下、RDS
のダッシュボードの「パラメータグループ」から新規で作成する際の各種設定。
- DBクラスタ用パラメータグループ
項目 | 設定 |
---|---|
パラメータグループファミリー | aurora-mysql5.7 |
タイプ | DB Cluster Parameter Group |
グループ名 | 任意(今回はblue-green-cl-param ) |
説明 | 任意(今回はblue-green-cl-param ) |
- DBインスタンス用パラメータグループ
項目 | 設定 |
---|---|
パラメータグループファミリー | aurora-mysql5.7 |
タイプ | DB Parameter Group |
グループ名 | 任意(今回はblue-green-param ) |
説明 | 任意(今回はblue-green-param ) |
パラメータの変更
作成したDBクラスタ用のパラメータグループを編集して、binlog_format
をMIXED
に変更します。
RDS
のダッシュボードから「パラメータグループ」を選択して、作成したblue-green-cl-param
にチェックをしてから「編集」を選択します。
変更可能なパラメータが大量に表示されるため、フィルタ欄にbinlog_format
と入力して「値」のリストボックスから「MIXED」を選択して、「変更の保存」で保存して終了です。
2024/07/29現在、導入当初のドキュメントの記載から更新されているようで、AWSのドキュメント上は「ROW」が推奨されておりますので、「MIXED」ではなく、「ROW」の使用を推奨します。
Aurora Clusterの作成
今回はテストなので必要最低限の設定のみ行うようにします。
項目が多いので設定した内容を以下表で記載。
項目 | 設定 | 備考 |
---|---|---|
データベース作成方法を選択 | 標準作成 | |
エンジンのタイプ | Amazon Aurora | |
エディション | Amazon Aurora MySQL互換エディション | まだPostgreSQLは対応していないためMySQLを選択 |
グローバルデータベース機能をサポートするバージョンを表示 | 無効 | |
並列クエリ機能をサポートするバージョンを表示 | 無効 | |
Serverless v2をサポートするバージョンを表示 | 無効 | |
利用可能なバージョン | Aurora (MySQL 5.7) 2.10.2 | デフォルトで選択済みのバージョンを指定 |
テンプレート | 開発/テスト | テスト目的なので今回は開発/テストを選択 |
DBクラスター識別子 | 任意(今回はblue-green-deploy-db ) |
|
マスターユーザー名 | admin | デフォルトのまま |
マスターパスワード | 任意 | 適当なパスワードを指定 |
DBインスタンスクラス | メモリ最適化クラス(r クラスを含む) | |
インスタンスタイプ | db.r6g.large | 最低限のスペックに変更 |
マルチAZ配置 | 別のAZでAuroraレプリカ/リーダーノードを作成する(可用性のスケーリングに推奨) | |
コンピューティングリソース | EC2コンピューティングリソースに接続 | 検証でEC2を使用したいため指定 |
EC2インスタンス | (検証用EC2) | |
Virtual Private Cloud(VPC) | AuroraとEC2が所属するVPC | 選択不可のため、デフォルトのまま EC2を接続しない場合は指定 |
DBサブネットグループ | rds-ec2-db-subnet-group-1 |
選択不可のため、デフォルトのまま EC2を接続しない場合は作成した blue-green-subnet を指定 |
パブリックアクセス | なし | |
VPCセキュリティグループ(ファイアウォール) | 新規作成 | |
新しいVPCセキュリティグループ名 | 任意(今回はBlue-Green-SG ) |
|
データベースポート | 3306 | |
データベース認証オプション | パスワード認証 | |
Performance Insightsをオンにする | 無効 | 今回はテストなので未設定 |
拡張モニタリングの有効課 | 無効 | 今回はテストなので未設定 |
最初のデータベース名 | 任意(今回はbluegreendb ) |
|
DBクラスターのパラメータグループ | blue-green-cl-param | 先ほど作成したものを指定 |
DBパラメータグループ | blue-green-param | 先ほど作成したものを指定 |
フェイルオーバー優先順位 | 指定なし | |
バックアップ保持期間 | 1日間 | デフォルトのまま |
スナップショットにタグをコピー | 有効 | デフォルトのまま |
暗号を有効化 | 無効 | |
バックトラックを有効にする | 無効 | |
ログのエクスポート | すべて無効 | |
IAMロール | RDSサービスにリンクされたロール | 選択不可のためデフォルトのまま |
マイナーバージョン自動アップグレードの有効化 | 無効 | |
メンテナンスウィンドウ | 設定なし | |
削除保護の有効化 | 無効 |
Blue/Greenデプロイの作成
いよいよBlue/Greenデプロイの構成を作成していきます。
DBクラスタがBlue/Greenデプロイのサポートがされている構成・バージョンであれば、以下のようにクラスタを選択して「アクション」を見ると「ブルー/グリーンデプロイの作成 - ベータ」という項目が表示されます。
※正式リリースされているはずなんですがまだベータ・・・
設定項目としては4つしか無いので、先程作成したDBと同様の設定を行っておきます。
以下設定は切り替え先となるDBクラスタの設定となるため、基のDBと合わせる必要はなく、行う作業によってエンジンバージョンやパラメータグループの指定を行います。
DB識別子も基のDBと合わせる必要は無く、基のDBと同じにしたとしても、ブルー/グリーンデプロイで作成されたことがわかる識別子が末尾に付与されるので、何でも良いです。(今回の例では基のDBと同じ識別子を指定)
以下表でも設定した内容を記載しておきます。
項目 | 設定 | 備考 |
---|---|---|
Blue-Green環境識別子 | blue-green-deploy-db | 今回は基のDBと同じに設定 |
Green DBインスタンスのエンジンバージョンを選択します。 | 5.7.mysql_aurora.2.10.2 - current | 今回は基のDBと同じに設定 |
Choose the DB cluster parameter group for green databases. | brue-green-cl-param | 今回は基のDBと同じに設定 |
Green DBインスタンスのDBパラメータグループを選択します。 | brue-green-param | 今回は基のDBと同じに設定 |
無事作成が完了すると以下の図のようにBlue
(基のDB)とGreen
(切り替え用のDB)の2クラスタが表示されます。
私の環境ではだいたい50分程度で作成完了しましたが、最初の5分程度でクラスタやインスタンスの作成が開始されていない場合は失敗しているので、後述する内容等を確認して頂き、再度実施してください。
Blue/Greenデプロイの検証
無事切替用のGreen環境が構築できたので、検証を行いながらBlue/Greenデプロイを試してみようと思います。
今回は検証用のEC2を使って以下の流れでDB更新した際にGreen環境のDBが更新されるのか、切替時のダウンタイムがどの程度かを検証してみます。
尚、私と同じように検証を行いたい方は、事前に適当なEC2インスタンスを準備しておいてください。
Blue/Greenデプロイ切り替え確認用EC2インスタンスの準備
切替時のダウンタイムを確認するため、確認用のEC2インスタンスを準備しておきます。
検証で使用するmysql
のクライアントは、amazon-linux-extras
でmariadb
をインストールすると一緒にインストールされるので、mariadb
をインストールします。
sudo su -
amazon-linux-extras install mariadb10.5
DB更新の確認
作成されたDBのエンドポイントを確認すると、基クラスタとなるBlueクラスタと新しく作成されたGreenクラスタのエンドポイント、AWSのドキュメントに変更されると記載されているリソースIDが以下のように設定されています。
- Blueクラスタ
エンドポイント名 | タイプ |
---|---|
blue-green-deploy-db.cluster-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com | ライターインスタンス |
blue-green-deploy-db.cluster-ro-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com | リーダーインスタンス |
DB識別子 | ロール | リソースID |
---|---|---|
blue-green-deploy-db | リージョン別クラスター | cluster-BCJ27RJM2AZSTPMAN6RCBKAOOU |
blue-green-deploy-db-instance-1 | ライターインスタンス | db-OQ37HBCGSYL3ZEB7KLGK3HG2AY |
blue-green-deploy-db-instance-1-ap-northeast-1a | リーダーインスタンス | db-E46PXHUHMAMLOKK22X2CTRVCQY |
- Greenクラスタ
エンドポイント名 | タイプ |
---|---|
blue-green-deploy-db-green-93roku.cluster-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com | ライターインスタンス |
blue-green-deploy-db-green-93roku.cluster-ro-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com | リーダーインスタンス |
DB識別子 | ロール | リソースID |
---|---|---|
blue-green-deploy-db-green-93roku | リージョン別クラスター | cluster-3QDYASSLHLPAKMZ7RXR3PEDE6I |
blue-green-deploy-db-instance-1-green-a8u1gc | ライターインスタンス | db-4T63D3MUEHIXZ4PZCU7JFTCAY4 |
blue-green-deploy-db-instance-1-ap-northeast-1a-green-yrwmwr | リーダーインスタンス | db-NH7KV6KN6MLRZLKIF5WVHP72C4 |
RDS
のBlue/Greenデプロイでは、Blue - Green間で同期が行われており、Green作成後にBlue側の更新が入った場合でも、Green側に同期される動作となるそうです。
そのため、実際にGreen側も更新されているのか、また、Green側を更新した場合にBlue側はどうなるかを確認してみようと思います。
Blue側DB更新時のGreen側確認
更新確認のため、Blue側のライターインスタンス、Green側のライターインスタンス両方に接続を行っておきます。
-p[パスワード]
の箇所はスペース無しでパスワードを入力。
mysql -h blue-green-deploy-db.cluster-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com -u admin -p[パスワード]
mysql -h blue-green-deploy-db-green-93roku.cluster-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com -u admin -p[パスワード]
まだテーブルが作成されていないため、Blue、GreenどちらもEmpty
で表示されるはずです。
MySQL [(none)]> use bluegreendb;
MySQL [bluegreendb]> show tables;
Empty set (0.002 sec)
この状態でBlue側に適当なテーブルを作成してみます。
MySQL [bluegreendb]> create table bgtest(
-> id int,
-> bluegreen varchar(255)
-> );
Query OK, 0 rows affected (0.027 sec)
MySQL [bluegreendb]> insert into bgtest(id, bluegreen) values(1,'blue');
Query OK, 1 row affected (0.015 sec)
作成後、Blue側、Green側どちらもコマンドで確認してみるとGreen側にデータが同期されていることが確認できるかと思います。
MySQL [bluegreendb]> show tables;
+-----------------------+
| Tables_in_bluegreendb |
+-----------------------+
| bgtest |
+-----------------------+
1 row in set (0.002 sec)
MySQL [bluegreendb]> select * from bgtest;
+------+-----------+
| id | bluegreen |
+------+-----------+
| 1 | blue |
+------+-----------+
1 row in set (0.002 sec)
Green側DB更新時のBlue側確認
Blue側が更新された場合でもGreen側に同期されることが確認できたため、次はGreen側を更新した場合にBlue側に同期されるかを確認してみます。
先程のテーブルに今度はGreen側からデータをインサートしてみます。
MySQL [bluegreendb]> insert into bgtest(id, bluegreen) values(2,'green');
Query OK, 1 row affected (0.009 sec)
作成後、Blue側、Green側どちらもコマンドで確認してみるとGreen側のデータは同期されていないことが確認できるかと思います。
MySQL [bluegreendb]> select * from bgtest;
+------+-----------+
| id | bluegreen |
+------+-----------+
| 1 | blue |
+------+-----------+
1 row in set (0.002 sec)
MySQL [bluegreendb]> select * from bgtest;
+------+-----------+
| id | bluegreen |
+------+-----------+
| 1 | blue |
| 2 | green |
+------+-----------+
2 rows in set (0.004 sec)
Blue/Greenデプロイの仕組みとして、切替先となるGreen側の動作に問題ないことが確認できたらBlue/Greenデプロイで切り替えて、DBデータに影響がないようにする仕組みとなるので、テスト中のGreenのデータ更新がBlue側に同期されてしまったら不整合が生じることから、Green側のデータは同期されないようになっているため、上記のような結果となります。
ちなみにこの状態でBlue側にid2
のデータを挿入すると、以下のようになります。
MySQL [bluegreendb]> select * from bgtest;
+------+-----------+
| id | bluegreen |
+------+-----------+
| 1 | blue |
| 2 | blue |
+------+-----------+
2 rows in set (0.002 sec)
MySQL [bluegreendb]> select * from bgtest;
+------+-----------+
| id | bluegreen |
+------+-----------+
| 1 | blue |
| 2 | green |
| 2 | blue |
+------+-----------+
3 rows in set (0.002 sec)
Blue/Greenデプロイによる切替の実施
切替前の時点ではBlue→Green方向の同期のみ行われることが確認できたため、今回の主題となるBlue/Greenデプロイによる切替を行ってみようと思います。
公式ページを見ると、Blue側とGreen側の切替を行う際、データ保護を行った上で切替が行われるため、1分程度のダウンタイムが発生すると記載されていることから、実際にどの程度の時間がかかるか、確認用スクリプトを作成してダウンタイムを計測してみます。
読み込み・書き込み確認用テーブルの作成
時間を記録したいので、先程とは別のbgcheck
という名前のテーブルを作成します。
MySQL [bluegreendb]> create table bgcheck(
-> id int,
-> date datetime
-> );
Query OK, 0 rows affected (0.055 sec)
MySQL [bluegreendb]> insert into bgcheck(id, date) values(1,cast(now() as datetime));
Query OK, 1 row affected (0.005 sec)
以下テーブルデータの結果。
MySQL [bluegreendb]> select * from bgcheck;
+------+---------------------+
| id | date |
+------+---------------------+
| 1 | 2022-12-10 11:38:44 |
+------+---------------------+
1 row in set (0.002 sec)
読み込み・書き込み確認用スクリプトの作成
Blue/Greenデプロイの仕組みとして、切替を行うと、元々Blue側に設定されているエンドポイントがGreen側に自動で切り替わることで、クライアント側からは同一のエンドポイントで通信ができる仕組みとなっています。
そのため、読み込み確認用スクリプトと書き込み確認用スクリプトを作成して、検証用EC2インスタンスからBlue側のライターインスタンスに対する読み込み・書き込み確認とBlue側のリーダーインスタンスに対する読み込み確認を行います。
雑なシェルですが、以下で作成。
#!/bin/bash
SLEEPTIME=1
ENDPOINT="blue-green-deploy-db.cluster-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com"
DBUSER="admin"
PASSWORD="[パスワード]"
DBNAME="bluegreendb"
TABLENAME="bgcheck"
COLUMN="date"
ID="1"
while true
do
echo "SELECT実行時間 $(mysql -h ${ENDPOINT} -u ${DBUSER} -p${PASSWORD} ${DBNAME} -ss -e "select ${COLUMN} from ${TABLENAME} WHERE id=${ID}")"
sleep ${SLEEPTIME}
done
#!/bin/bash
SLEEPTIME=1
ENDPOINT="blue-green-deploy-db.cluster-ro-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com"
DBUSER="admin"
PASSWORD="[パスワード]"
DBNAME="bluegreendb"
TABLENAME="bgcheck"
COLUMN="date"
ID="1"
while true
do
echo "SELECT実行時間 $(mysql -h ${ENDPOINT} -u ${DBUSER} -p${PASSWORD} ${DBNAME} -ss -e "select ${COLUMN} from ${TABLENAME} WHERE id=${ID}")"
sleep ${SLEEPTIME}
done
#!/bin/bash
SLEEPTIME=1
ENDPOINT="blue-green-deploy-db.cluster-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com"
DBUSER="admin"
PASSWORD="[パスワード]"
DBNAME="bluegreendb"
TABLENAME="bgcheck"
COLUMN="date"
ID="1"
while true
do
echo "UPDATE実行時間 $(date "+%Y-%m-%d %H:%M:%S")"
mysql -h ${ENDPOINT} -u ${DBUSER} -p${PASSWORD} ${DBNAME} -ss -e "update ${TABLENAME} set ${COLUMN}=cast(now() as datetime) where id=${ID};"
sleep ${SLEEPTIME}
done
dbwrite.sh
(書き込み確認用スクリプト)で1秒ごとにID=1
の時間を更新し、dbread.sh
(読み込み確認用スクリプト)で1秒ごとにID=1
の時間を読み取るようにして、読み込み、書き込みのダウンタイムを計測します。
Blue/Greenデプロイによる切替
実際に切替を行うためには「ブルー/グリーンデプロイ」ロールを選択して、「アクション」→「切り替え」を行います。
切替確認と、切替失敗とみなすタイムアウトの設定を行い、「切り替え」を選択することで切替が開始されます。
無事成功すると元々BlueだったクラスタとDBインスタンスは識別子の末尾に-old1
という名前が付与され、元々GreenだったクラスタとDBインスタンスは元々Blueだった識別子を継承するような動作となります。
また、エンドポイントについて、Blueクラスタ側は切替前と同様で、Greenクラスタ側は元々のBlueクラスタのエンドポイント名に-old1
が付与された名前となります。
リソースIDについては、Blue/Greenデプロイによりリソースが切り替わったことから、Blue側のリソースIDは元々Green側だったリソースIDに変化、Green側のリソースIDは元々Blue側だったリソースIDに変化しています。
- 切替後のBlueクラスタ
エンドポイント名 | タイプ |
---|---|
blue-green-deploy-db.cluster-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com | ライターインスタンス |
blue-green-deploy-db.cluster-ro-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com | リーダーインスタンス |
DB識別子 | ロール | リソースID |
---|---|---|
blue-green-deploy-db | リージョン別クラスター | cluster-3QDYASSLHLPAKMZ7RXR3PEDE6I |
blue-green-deploy-db-instance-1 | ライターインスタンス | db-4T63D3MUEHIXZ4PZCU7JFTCAY4 |
blue-green-deploy-db-instance-1-ap-northeast-1a | リーダーインスタンス | db-NH7KV6KN6MLRZLKIF5WVHP72C4 |
- 切替後のGreenクラスタ
エンドポイント名 | タイプ |
---|---|
blue-green-deploy-db-old1.cluster-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com | ライターインスタンス |
blue-green-deploy-db-old1.cluster-ro-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com | リーダーインスタンス |
DB識別子 | ロール | リソースID |
---|---|---|
blue-green-deploy-db-old1 | リージョン別クラスター | cluster-BCJ27RJM2AZSTPMAN6RCBKAOOU |
blue-green-deploy-db-instance-1-old1 | ライターインスタンス | db-OQ37HBCGSYL3ZEB7KLGK3HG2AY |
blue-green-deploy-db-instance-1-ap-northeast-1a-old1 | リーダーインスタンス | db-E46PXHUHMAMLOKK22X2CTRVCQY |
Blue→Greenの同期については、切替のタイミングでBlue→Green方向の同期が停止され、Green側は以下のようにライターインスタンスに接続しても更新できない状態となるようです。
MySQL [bluegreendb]> insert into bgtest(id, bluegreen) values(3,'green');
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
切替時間の確認
Blue/Green切替時に実行していた3つのスクリプトの結果を確認します。
結論から言うと、私の検証方法ではライターインスタンスに対しては2分程度のダウンタイムが発生しましたが、リーダーインスタンスに対してはダウンタイムは発生しませんでした。
以下それぞれのスクリプト結果の抜粋。
SELECT実行時間 2022-12-10 12:24:51
SELECT実行時間 2022-12-10 12:24:52
SELECT実行時間 2022-12-10 12:24:52
ERROR 2002 (HY000): Can't connect to MySQL server on 'blue-green-deploy-db.cluster-cs5yre5qdxto.ap-northeast-1.rds.ama' (115)
SELECT実行時間
SELECT実行時間 2022-12-10 12:24:52
SELECT実行時間 2022-12-10 12:27:07
SELECT実行時間 2022-12-10 12:27:08
SELECT実行時間 2022-12-10 12:24:52
SELECT実行時間 2022-12-10 12:24:52
SELECT実行時間 2022-12-10 12:24:52
SELECT実行時間 2022-12-10 12:27:07
SELECT実行時間 2022-12-10 12:27:08
SELECT実行時間 2022-12-10 12:27:09
UPDATE実行時間 2022-12-10 12:24:52
UPDATE実行時間 2022-12-10 12:24:53
ERROR 1290 (HY000) at line 1: The MySQL server is running with the --read-only option so it cannot execute this statement
UPDATE実行時間 2022-12-10 12:24:54
ERROR 1290 (HY000) at line 1: The MySQL server is running with the --read-only option so it cannot execute this statement
UPDATE実行時間 2022-12-10 12:24:55
ERROR 2002 (HY000): Can't connect to MySQL server on 'blue-green-deploy-db.cluster-cs5yre5qdxto.ap-northeast-1.rds.ama' (115)
UPDATE実行時間 2022-12-10 12:27:07
UPDATE実行時間 2022-12-10 12:27:08
スクリプトの動作としては、dbread.sh
とdbwrite.sh
は切替後、12:24:52〜12:27:07の間、エラー出力&結果出力停止、dbread_reader.sh
は切替後も結果が止まることなく出力&復旧タイミングで時間更新されました。
上記検証結果より、Blue/Green切替時、ライターインスタンスに対してはRead
もWrite
も行えなくなり、リーダーインスタンスに対してはダウンタイムなくRead
が行えるようです。
尚、元々Blue側だったクラスタとDBインスタンスは自動で削除されず、残ったままだと再度Blue/Greenデプロイを作成することができないので、不要となったら手動で削除しましょう。
切替自体は問題なくできましたが、唯一気になったのは、2022年12月現在、Blue/Greenの切り替えはできますが、切り戻しは行えません。
そのため、Blue/Green切替後に切り戻すことになった場合はスナップショットから復元したりする必要があるということは覚えておきましょう。
検証結果まとめ
検証結果が長くなったため、以下まとめ。
- Blue/Green切替前の段階ではBlue→Greenへデータ同期が行われる
- Blue/Green切替時、リーダーインスタンスへの読み込みはダウンタイムなく可能
- Blue/Green切替時、ライターインスタンスへの読み込み・書き込みは2分程度のダウンタイムがある
- Blue/Green切替後、旧クラスタ・インスタンスは読み込み専用となる
- Blue/Green切替後、旧クラスタ・インスタンスは自動で削除されない
- Blue/Green切替後、旧クラスタ・インスタンスが残っていると再度Blue/Greenデプロイはできない
- Blue/Green切替後、旧クラスタ・インスタンスに切り戻しはできない
旧クラスタ・インスタンスの削除方法
不要となった旧クラスタ・インスタンスを削除するには、最初に「ブルー/グリーンデプロイ」ロールを削除してから旧DBインスタンスを削除することで削除できます。
この方法で削除しないと、後述のように「ブルー/グリーンデプロイ」ロールが削除できなくなるようなので注意しましょう。
「ブルー/グリーンデプロイ」ロールが削除されれば、通常のDBクラスタ削除と同様、クラスタに所属するDBインスタンスを全て削除することで旧クラスタを削除できます。
手順を実施していて詰まった部分と補足
記事的にはすんなり進んでいるように書いていますが、あまりRDS
やDB
自体に詳しくないこともあり、ちょこちょこと詰まったので以下で詰まった点を書いておきます。
- デフォルトのパラメータグループの値を変更できない
- パラメータグループを変更したら再起動が必要
- サブネットグループを3AZで定義していないとBlue/Greenの作成に失敗する
- 旧クラスタ・インスタンスを削除する際にBlue/Greenデプロイのロールから削除しないと消せなくなる
デフォルトのパラメータグループの値を変更できない
今回のBlue/Greenデプロイの問題というより、パラメータグループの仕様を私が知らなかっただけですが、デフォルトで作成されるパラメータグループは値を編集することができません。
binlog_format
の値を変更するためには「事前準備」で実施している通り、新規でパラメータグループを作成して編集しておく必要がありました。
パラメータグループを変更したら再起動が必要
パラメータグループのパラメータのうち、「適用タイプ」が「static」のパラメータはインスタンスの再起動を行わないと適用されません。
※「dynamic」のパラメータは再起動無しで適用可能
binlog_format
は適用タイプが「static」のため、再起動が必要となるので、本番環境へ適用する際には気をつけましょう。
サブネットグループを3AZで定義していないとBlue/Greenの作成に失敗する
今回これが一番ハマりました。。。
RDS
でBlue/Greenデプロイを実施する場合、元々の構成を2AZ
で構成していたとしても、サブネットグループを3AZ
にしておかないと、Blue/Greenデプロイの作成は開始されますが、インスタンスが作成されず、プロビジョン状態から進まない状態となります。
今回紹介した手順では検証用のEC2インスタンスと接続するために「EC2コンピューティングリソースに接続」を指定したためサブネットグループは指定できず勝手にサブネットグループが作られましたが、EC2インスタンスと接続しないようにすれば既存のサブネットグループを選択することができます。
最初試したときには動作確認をするだけの目的だったため、元々2AZ
で作っていたサブネットグループを選択してそのまま使用していたことから、何度やってもプロビジョン状態から進まず、途方に暮れていました。
たまたま3AZ
であれば成功したという話を聞いて解決しましたが、その話を聞かなければ、まだまだお金と時間が無駄に消えていっていたでしょう。。。
旧クラスタ・インスタンスを削除する際にBlue/Greenデプロイのロールから削除しないと消せなくなる
不要となった旧クラスタ・インスタンス削除する際、インスタンスを先に削除すると「ブルー/グリーンデプロイ」ロールの項目だけ残ってしまい、消せなくなりました。(Blue/Green両方のインスタンスを全て消したら消えました)
もしかしたらしばらく待っていたら消えたかもしれませんが、「ブルー/グリーンデプロイ」ロールの項目だけ残ってしまっていると、再度Blue/Greenデプロイを行おうとしても、「アクション」に「ブルー/グリーンデプロイの作成 - ベータ」の項目が出てこないため、必ず「ブルー/グリーンデプロイ」ロールから消すようにしましょう。
おわりに
検証した結果、気にしないといけない箇所はありますが、要点さえ抑えておけば運用で大活躍できる機能だと感じました。
この記事が少しでも皆様の日々の運用の参考になれば幸いです。