ヌーラボブログリレー2024 for Tech Advent Calendar 2024の15日目の記事です。
こんにちは!ウェブサイト課の野津です。
先週、フルマラソンを人生初完走してきました。
走り続けることがこんなにも大変だとは…身に染みて感じています。
チームとしてもゴールに向けてマラソンを続けていますので、よろしければ直近の取り組みをご覧ください。
2024年下半期のヌーラボにおけるアクセシビリティ向上の取り組みを振り返る
ウェブサイト課が2024年に取り組んだアクセシビリティ向上活動をふり返る
アクセシビリティカンファレンス福岡2024に参加してきた #fukuoka_a11yconf
さて、今回はウェブサイトで使用しているデータベースサーバで行ったAurora MySQLのアップグレードについて振り返ります。
目次
Blue/Green デプロイとは?
Blue/Green デプロイとは、ソフトウェアのリリースやアップグレード等を行う際にダウンタイムを最小限に抑えるデプロイ方法です。
Blueと呼ばれる環境が現在動いている環境で、GreenはBlueを複製して作られた環境です。
このGreenの環境で必要な変更を行い(今回の場合はDBのアップグレード)、問題がなければユーザーのアクセス先をBlue環境からGreen環境に切り替えます。この切り替えが素早く行われるため、ダウンタイムはほとんど発生しません。
(実際にやってみた結果、今回の環境では5分程度で切り替わりました)
AWSが提供するBlue/Green デプロイには切り替え後の切り戻し機能はありませんが、問題が発生した場合は手動で切り戻すこともできます。
DBをできるだけ止めずにアップグレードをするとなると準備がかなり大変です。一般的には以下のような手順を踏む必要があります。
- 動作している環境のRDSスナップショットを作成し、そこからGreen環境を作成
- GreenのDBをアップグレード
- BlueとGreenでデータ同期をするためにレプリケーションユーザを作成
- Blueでバイナリログを有効にしてレプリケーションを有効化
- データ同期の確認
- RDSのエンドポイントを変更し、BlueからGreenに接続先を変更
- 動作確認
この一連のBlue/Green デプロイの機能をAWSがマネージドで提供しており、コンソールポチポチで利用できます。
ちなみに、私は初めてこのデプロイ方法を聞いた時、BlueとGreenどっちがどっちやねん状態になったので、BlueはBefore(移行前)、GreenはGoとかGoal(移行後)と覚えました。
また、Blue/Green デプロイの注意点として、2つの環境を同時に用意する必要があるため、通常の2倍の費用がかかります。検証に時間をかけたり休日を挟むと結構な費用が発生するため、留意する必要があります。(特にRDSは高い!)
なぜアップグレードにBlue/Green デプロイを使用したか
アップグレードの他の手順としては、Blue/Green デプロイの他に、現在のRDSをそのままアップグレードする方法(インプレースアップグレード)があり、更新頻度がそこまで高くないウェブサイトであればそれでも問題ないと考えましたが、前者であればダウンタイムが短い点、切り戻しが簡易である点、また使ったことのない機能を使う良いチャンスだということもあり、今回Blue/Green デプロイを使用してアップグレードを行いました。
アップグレード実施の流れ
実際にどのような流れでアップグレードをしたのかをまとめます。
準備
- 実施時期の決定
現行バージョンのサポート期限を確認し、どの程度作業に時間がかかるかを逆算して作業を進めます。想定外の事象が起こることを考え、余裕を持った計画を立てます。 - バージョン決定
現行のバージョンからどのバージョンにアップグレードをするかを決定します。
アップグレード先のバージョンのサポート期限等を考慮します。 - ダウンタイムの許容範囲確認
提供するサービスがどの程度停止することを許容できるか確認します。
どの時間帯であれば影響が少ないのか、事前に告知が必要かどうかを決定します。 - 手順や注意事項等の調査
アップグレードするにあたって参考となる手順や注意事項がないか調査します。
AWSの公式情報をベースに、社内のBacklog課題、ブログ、AI活用を経て、ざっくりやることや注意点をまとめます。
色々な情報を入手できることに感謝する反面、情報過多で時間を使いすぎないように、調査する時間を決めて実施します。
今回得た情報が以下です。
- インスタンスタイプがdb.t3.smallの場合、変更が必要 (Aurora MySQL 8.0 における制約)
- Blue側でパラメーターのbinlog有効化が必要
- 切り替え後はBlue/Green デプロイを削除しないと旧ブルー環境のDBへの書き込みはできない
本番環境のスナップショットでアップグレードテストをする
実際に手を動かす作業ですが、早い段階で実施可能なアップグレードテストを行います。
これは本番環境のRDSのスナップショットを使って単体でアップグレードを行い、エラーが出ないかを確認するものです。
具体的には、以下の手順で進めます。
- 本番稼働のRDSからスナップショットを作成
- スナップショットからRDSを作成
- アップグレードするバージョンのパラメーターグループを作成
- DBを変更し、エンジンバージョンをアップグレードする(所要時間は1時間でした)
- アップグレードが完了したらログ(upgrade-prechecks.log)を確認してエラーが出ていないことを確認する
アップグレード手順書を作成する
検証環境及び本番環境で使用するアップグレード手順を作成します
この手順をベースに検証環境のDBをアップグレードし、その結果を手順に反映して、本番環境でのアップグレード作業に臨みます。
この時点での手順は完璧を求めずにざっくりと作成し、検証環境で見つかったことをこまめに反映させます。
手順はBacklogの「ドキュメント機能」(β版)を使って書きました。
ドキュメント機能はレビュー時にコメントを入れたり、リアルタイムで複数人が編集をすることができます。自動保存されるため、手順書作成でやりがちな「わしの3時間の作業が消えた」を防げます。
検証環境をアップグレードする
作成した手順書を元に検証環境をアップグレードします。
具体的には以下のことを実施しました。
1.RDSの事前スナップショット作成
2. aurora-mysql用のパラメーターグループのBinlog有効化
クラスタ用のパラメーターグループ(現在と同じファミリー)を新規作成し、binlog_format をROWからMIXEDに変更
3. 既存のパラメーターグループbinlog_format以外に差分がないか確認する
4. 新しく移行先のバージョンのパラメーターグループを作成し、既存の設定を反映する
5. DBインスタンスタイプを変更
5-1. リーダーインスタンスのインスタンスタイプ変更:db.t3.small → db.t4g.medium
5-2. 既存のクラスタのパラメーターグループを新規作成したものに変更
5-3. リーダーインスタンスが再起動して変更されたらフェールオーバーさせる
5-4. ライターインスタンスのインスタンスタイプ変更:db.t3.small → db.t4g.medium
5-5. 既存のクラスタのパラメーターグループを新規作成したものに変更
5-6. 上記全てが変更されたことを確認
6. Binlog設定を適用
7. EC2インスタンスからBinlog_formatが変更されているかを確認する(MIXEDになっていること)
# wp db query "SHOW VARIABLES LIKE 'binlog_format';" +---------------+-------+ | Variable_name | Value | +---------------+-------+ | binlog_format | MIXED | +---------------+-------+
8. Blue/Green デプロイの作成
コンソールで操作 「ブルー/グリーンデプロイの作成」を選択して作成する
利用可能になるまでの所要時間を記録する (今回は1時間程度だった)
9. 同期状態の確認
EC2インスタンスからDBに接続して同期状態を確認する(エンドポイントはGreenの方を指定)
mysql -h db-website-blog-dev-cluster.cluster-xxx.ap-northeast-1.rds.amazonaws.com -P xxxx -u xxxx -p SHOW REPLICA STATUS\G 以下の項目を確認して、正常に同期されていることを確認する - Replica_IO_Running が Yes になっていること(レプリケーションのI/Oスレッドが正常に稼働している) - Replica_SQL_Running が Yes になっていること(レプリケーションのSQLスレッドが正常に稼働している) - Replica_IO_State が No になっていないこと。#No だとI/Oスレッドが停止している - Last_Errorが空欄になっていること(エラーが発生していないこと) - Seconds_Behind_Source の値が大きすぎる値になっていないこと(ソースからの遅れ:0であれば遅れていない)
10. Green環境での動作確認
アップグレードしたDBでの動作に問題がないか確認する。
ここでの動作確認はSQLクエリでの確認となるため、ウェブサイトの見た目の確認といったところまではできない。
11. 切り替え(カットオーバー)
コンソールで操作 「切り替え」を選択して実行する。
所要時間を記録する(今回は5分程度でした)
12. バージョン確認
EC2インスタンスからDBに接続してバージョンが上がっていることを確認する
13. 動作確認
アップグレード後の動作確認をする
14. 切り替え完了後、切り戻しテストの実施(新しいブルーと古いブルーを交換)
検証環境で切り戻しテストを一度実施する(所要時間を記録:20分程度でした)
切り戻しはDB識別子を変更することでエンドポイントを変更し、向き先を変更することで古いブルー環境を参照させます。
DB識別子はユニークである必要があるため1台ずつ変更が必要&変更にあたって再起動が発生するため時間がかかります(各インスタンス毎に数分)
また、古いブルー環境(アップグレード前の環境)は読み取りオペレーションのみを許可する設定になっているため、パラメーターのread_onlyを0にした上でBlue/Green デプロイを削除する必要があります。(ブルー/グリーンデプロイの切り替え)
- db-website-blog-dev-cluster-bgを削除して切り離す(古いブルー、新しいブルーの表示が消える)
- 新しいブルーのdb-website-blog-dev-0を変更 (Clusterとinstanceの2箇所を変更:末尾にbakつける)
- 新しいブルーのdb-website-blog-dev-1を変更 (instanceのみ変更:末尾にbakつける)
- 古いブルーのdb-website-blog-dev-0-old1を変更
- Clusterとinstanceの2箇所を変更[old1を取る]
- Clusterパラメーターグループとインスタンスパラメーターグループのread_onlyを0にする
- 古いブルーのdb-website-blog-dev-1-old1を変更
- instanceのみ変更[old1を取る]
- インスタンスパラメーターグループのread_onlyを0にする
- 切り替わってバージョンが戻っていることを確認する
15. 再度、切り替えを実施(切り戻しをした場合のみ)
Blue/Green デプロイの作成から同様に実施する(データ移行が不要な場合は再度切り戻しでも良い)
16. 切り替え後(切り替え後に実施する作業)
Blue/Green デプロイを削除する(削除していない場合)
旧Blue環境を削除する(削除しないと課金されますので注意)
検証環境の結果を手順書に反映する
この作業は検証環境のアップデートと並行で実施しました。
取りこぼしがないように、気づいた点は直ぐに手順書を更新するようにしました。
本番環境をアップグレードする
ここまで来れば後は、検証環境での手順を本番環境用に置き換えて、同様の手順でアップグレードを行うだけとなります。(置き換わるのはDB識別子、エンドポイントぐらいでした)
計画通り、ユーザーに影響が出ないように留意して実施します。
おわりに
今回の対象はパラメーターの変更もほとんど発生せず、リアルタイムで更新が発生する環境ではなかったため、比較的スムーズにアップグレードを行うことができました。
ただ、ダウンタイムをできるだけ抑えてアップグレードしていくためには事前の準備などに労力がかかります。
そういった作業の負担を軽くしてくれるマネージドサービスの有り難さを改めて感じました。