search
LoginSignup
1

posted at

updated at

Amazon AuroraでBlue/Greenデプロイを検証する。

はじめに

2022年のAWS re:Inventにて発表となったRDSでのBlue/Greenデプロイが、すぐにでも導入したい内容だったので、実験がてら検証してみたいと思います。

以下公式の発表と参考サイト

今回の発表について

今回、新機能として紹介されましたが、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/AuroraBlue/Greenデプロイを実施するためにはDBクラスタ用のパラメータグループbinlog_formatMIXEDに変更する必要があります。

binlog_formatのデフォルトはOFFなので、Aurora作成時に差し替えられるよう前もってbinlog_formatMIXEDに変更したパラメータグループを作成しておきます。

尚、デフォルトのパラメータグループはパラメータの変更ができないため新規で作成してパラメータ変更を行う必要があります。

今回の場合、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_formatMIXEDに変更します。

RDSのダッシュボードから「パラメータグループ」を選択して、作成したblue-green-cl-paramにチェックをしてから「編集」を選択します。

Monosnap_20221210_105708.png

変更可能なパラメータが大量に表示されるため、フィルタ欄にbinlog_formatと入力して「」のリストボックスから「MIXED」を選択して、「変更の保存」で保存して終了です。

Monosnap_20221210_110307.png

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デプロイのサポートがされている構成・バージョンであれば、以下のようにクラスタを選択して「アクション」を見ると「ブルー/グリーンデプロイの作成 - ベータ」という項目が表示されます。
※正式リリースされているはずなんですがまだベータ・・・

Monosnap_20221210_140253.png

設定項目としては4つしか無いので、先程作成したDBと同様の設定を行っておきます。

以下設定は切り替え先となるDBクラスタの設定となるため、基のDBと合わせる必要はなく、行う作業によってエンジンバージョンやパラメータグループの指定を行います。

DB識別子も基のDBと合わせる必要は無く、基のDBと同じにしたとしても、ブルー/グリーンデプロイで作成されたことがわかる識別子が末尾に付与されるので、何でも良いです。(今回の例では基のDBと同じ識別子を指定)

Monosnap_20221210_140617.png

以下表でも設定した内容を記載しておきます。

項目 設定 備考
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分程度でクラスタやインスタンスの作成が開始されていない場合は失敗しているので、後述する内容等を確認して頂き、再度実施してください。

Monosnap_20221210_202906.png

Blue/Greenデプロイの検証

無事切替用のGreen環境が構築できたので、検証を行いながらBlue/Greenデプロイを試してみようと思います。

今回は検証用のEC2を使って以下の流れでDB更新した際にGreen環境のDBが更新されるのか、切替時のダウンタイムがどの程度かを検証してみます。

尚、私と同じように検証を行いたい方は、事前に適当なEC2インスタンスを準備しておいてください。

Blue/Greenデプロイ切り替え確認用EC2インスタンスの準備

切替時のダウンタイムを確認するため、確認用のEC2インスタンスを準備しておきます。

検証で使用するmysqlのクライアントは、amazon-linux-extrasmariadbをインストールすると一緒にインストールされるので、mariadbをインストールします。

mysqlクライアントインストール
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

RDSBlue/Greenデプロイでは、Blue - Green間で同期が行われており、Green作成後にBlue側の更新が入った場合でも、Green側に同期される動作となるそうです。

そのため、実際にGreen側も更新されているのか、また、Green側を更新した場合にBlue側はどうなるかを確認してみようと思います。

Blue側DB更新時のGreen側確認

更新確認のため、Blue側のライターインスタンス、Green側のライターインスタンス両方に接続を行っておきます。

-p[パスワード]の箇所はスペース無しでパスワードを入力。

Blue側ライターインスタンスへの接続
mysql -h blue-green-deploy-db.cluster-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com -u admin -p[パスワード]
Green側ライターインスタンスへの接続
mysql -h blue-green-deploy-db-green-93roku.cluster-cs5yre5qdxto.ap-northeast-1.rds.amazonaws.com -u admin -p[パスワード]

まだテーブルが作成されていないため、Blue、GreenどちらもEmptyで表示されるはずです。

bluegreendbのテーブル確認
MySQL [(none)]> use bluegreendb;
MySQL [bluegreendb]> show tables;
Empty set (0.002 sec)

この状態でBlue側に適当なテーブルを作成してみます。

Blue側テーブルの作成
MySQL [bluegreendb]> create table bgtest(
    -> id int,
    -> bluegreen varchar(255)
    -> );
Query OK, 0 rows affected (0.027 sec)
Blue側テーブルへのインサート
MySQL [bluegreendb]> insert into bgtest(id, bluegreen) values(1,'blue');
Query OK, 1 row affected (0.015 sec)

作成後、Blue側、Green側どちらもコマンドで確認してみるとGreen側にデータが同期されていることが確認できるかと思います。

Blue側テーブル作成後のGreen側テーブル確認
MySQL [bluegreendb]> show tables;
+-----------------------+
| Tables_in_bluegreendb |
+-----------------------+
| bgtest                |
+-----------------------+
1 row in set (0.002 sec)
Blue側テーブルデータインサート後のGreen側テーブルデータ確認
MySQL [bluegreendb]> select * from bgtest;
+------+-----------+
| id   | bluegreen |
+------+-----------+
|    1 | blue      |
+------+-----------+
1 row in set (0.002 sec)

Green側DB更新時のBlue側確認

Blue側が更新された場合でもGreen側に同期されることが確認できたため、次はGreen側を更新した場合にBlue側に同期されるかを確認してみます。

先程のテーブルに今度はGreen側からデータをインサートしてみます。

Green側テーブルへのインサート
MySQL [bluegreendb]> insert into bgtest(id, bluegreen) values(2,'green');
Query OK, 1 row affected (0.009 sec)

作成後、Blue側、Green側どちらもコマンドで確認してみるとGreen側のデータは同期されていないことが確認できるかと思います。

Green側テーブルデータインサート後のBlue側テーブルデータ確認
MySQL [bluegreendb]> select * from bgtest;
+------+-----------+
| id   | bluegreen |
+------+-----------+
|    1 | blue      |
+------+-----------+
1 row in set (0.002 sec)
Green側テーブルデータインサート後のGreen側テーブルデータ確認
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のデータを挿入すると、以下のようになります。

Blue側テーブルデータインサート後のBlue側テーブルデータ確認
MySQL [bluegreendb]> select * from bgtest;
+------+-----------+
| id   | bluegreen |
+------+-----------+
|    1 | blue      |
|    2 | blue      |
+------+-----------+
2 rows in set (0.002 sec)
Blue側テーブルデータインサート後のGreen側テーブルデータ確認
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という名前のテーブルを作成します。

bgcheckテーブルの作成
MySQL [bluegreendb]> create table bgcheck(
    -> id int,
    -> date datetime
    -> );
Query OK, 0 rows affected (0.055 sec)
bgcheckテーブルへのインサート
MySQL [bluegreendb]> insert into bgcheck(id, date) values(1,cast(now() as datetime));
Query OK, 1 row affected (0.005 sec)

以下テーブルデータの結果。

bgcheckテーブルデータ確認
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側のリーダーインスタンスに対する読み込み確認を行います。

雑なシェルですが、以下で作成。

dbread.sh(読み込み確認用スクリプト(Writerインスタンス用))
#!/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
dbread_reader.sh(読み込み確認用スクリプト(Readerインスタンス用))
#!/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
dbwrite.sh(書き込み確認用スクリプト)
#!/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デプロイによる切替

実際に切替を行うためには「ブルー/グリーンデプロイ」ロールを選択して、「アクション」→「切り替え」を行います。

Monosnap_20221210_211125.png

切替確認と、切替失敗とみなすタイムアウトの設定を行い、「切り替え」を選択することで切替が開始されます。

Monosnap_20221210_211329.png

無事成功すると元々BlueだったクラスタとDBインスタンスは識別子の末尾に-old1という名前が付与され、元々GreenだったクラスタとDBインスタンスは元々Blueだった識別子を継承するような動作となります。

Monosnap_20221210_213240.png

また、エンドポイントについて、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側は以下のようにライターインスタンスに接続しても更新できない状態となるようです。

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分程度のダウンタイムが発生しましたが、リーダーインスタンスに対してはダウンタイムは発生しませんでした。

以下それぞれのスクリプト結果の抜粋。

dbread.sh(読み込み確認用スクリプト(Writerインスタンス用))の結果抜粋
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
dbread_reader.sh(読み込み確認用スクリプト(Readerインスタンス用))の結果抜粋
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
dbwrite.sh(書き込み確認用スクリプト)の結果抜粋
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.shdbwrite.shは切替後、12:24:52〜12:27:07の間、エラー出力&結果出力停止、dbread_reader.shは切替後も結果が止まることなく出力&復旧タイミングで時間更新されました。

上記検証結果より、Blue/Green切替時、ライターインスタンスに対してはReadWriteも行えなくなり、リーダーインスタンスに対してはダウンタイムなく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インスタンスを削除することで削除できます。

この方法で削除しないと、後述のように「ブルー/グリーンデプロイ」ロールが削除できなくなるようなので注意しましょう。

Monosnap_20221210_220946.png

Monosnap_20221210_221240.png

ブルー/グリーンデプロイ」ロールが削除されれば、通常のDBクラスタ削除と同様、クラスタに所属するDBインスタンスを全て削除することで旧クラスタを削除できます。

Monosnap_20221210_224414.png

手順を実施していて詰まった部分と補足

記事的にはすんなり進んでいるように書いていますが、あまりRDSDB自体に詳しくないこともあり、ちょこちょこと詰まったので以下で詰まった点を書いておきます。

デフォルトのパラメータグループの値を変更できない

今回のBlue/Greenデプロイの問題というより、パラメータグループの仕様を私が知らなかっただけですが、デフォルトで作成されるパラメータグループは値を編集することができません。

binlog_formatの値を変更するためには「事前準備」で実施している通り、新規でパラメータグループを作成して編集しておく必要がありました。

パラメータグループを変更したら再起動が必要

パラメータグループのパラメータのうち、「適用タイプ」が「static」のパラメータはインスタンスの再起動を行わないと適用されません。
※「dynamic」のパラメータは再起動無しで適用可能

binlog_formatは適用タイプが「static」のため、再起動が必要となるので、本番環境へ適用する際には気をつけましょう。

サブネットグループを3AZで定義していないとBlue/Greenの作成に失敗する

今回これが一番ハマりました。。。

RDSBlue/Greenデプロイを実施する場合、元々の構成を2AZで構成していたとしても、サブネットグループを3AZにしておかないと、Blue/Greenデプロイの作成は開始されますが、インスタンスが作成されず、プロビジョン状態から進まない状態となります。

今回紹介した手順では検証用のEC2インスタンスと接続するために「EC2コンピューティングリソースに接続」を指定したためサブネットグループは指定できず勝手にサブネットグループが作られましたが、EC2インスタンスと接続しないようにすれば既存のサブネットグループを選択することができます。

最初試したときには動作確認をするだけの目的だったため、元々2AZで作っていたサブネットグループを選択してそのまま使用していたことから、何度やってもプロビジョン状態から進まず、途方に暮れていました。

たまたま3AZであれば成功したという話を聞いて解決しましたが、その話を聞かなければ、まだまだお金と時間が無駄に消えていっていたでしょう。。。

旧クラスタ・インスタンスを削除する際にBlue/Greenデプロイのロールから削除しないと消せなくなる

不要となった旧クラスタ・インスタンス削除する際、インスタンスを先に削除すると「ブルー/グリーンデプロイ」ロールの項目だけ残ってしまい、消せなくなりました。(Blue/Green両方のインスタンスを全て消したら消えました)

もしかしたらしばらく待っていたら消えたかもしれませんが、「ブルー/グリーンデプロイ」ロールの項目だけ残ってしまっていると、再度Blue/Greenデプロイを行おうとしても、「アクション」に「ブルー/グリーンデプロイの作成 - ベータ」の項目が出てこないため、必ず「ブルー/グリーンデプロイ」ロールから消すようにしましょう。

おわりに

検証した結果、気にしないといけない箇所はありますが、要点さえ抑えておけば運用で大活躍できる機能だと感じました。

この記事が少しでも皆様の日々の運用の参考になれば幸いです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
1