はじめに
イタンジ株式会社の稲垣です。ノマドクラウドという不動産仲介向けのSaaSを開発しています。 最近はACVIにハマっており、本当はACVIの記事を書こうと思ったのですが、先日表題のようなネタになることをしてしまったのでそれについて書きます。
弊社サービスのノマドクラウドでは、DBとしてAWS RDSを採用しています。 RDSのデータベースエンジンとして、以前はMySQL 5.7 (以下MySQLと記載)を使用していました。
このデータベースエンジンをAurora MySQL(以下Auroraと記載)に変更したので、備忘録としてその手順と注意点をブログに残していきます。
モチベーション
そもそもなぜデータベースエンジンを変更する必要があったのでしょうか。
MySQLではバージョン5.7.8以降でJSON型が使えるようになりました。 カラムにJSONを直接保存し、jsonの値で検索できたりするようになるとても便利な機能です。 ノマドクラウドに今後実装する機能において、このJSON型があると実装しやすいと判断し、5.7.8以上にアップデートする必要が生じました。
しかし、AWS RDSのMySQLではバージョン5.7.43までしか対応しておらず、JSON型を使えませんでした。 そのため、JOSN型を取り扱えるMySQLと互換性のあるAurora MySQL 5.7に変更することにしました。
またMySQLのときの冗長化はシンプルなprimary/replica構成で、ライターとリーダーが完全に分かれていました。 Auroraに変更することで、DBクラスターを形成しやすくなり、障害発生時の可用性が上がるという副次的な効果も期待しました。
やったこと
AWS Route 53でDB接続用のプライベートホストの作成
ノマドクラウドのRailsアプリケーションでは、DBへの接続情報としてRDSが提供するエンドポイント(db-name.cluster-xxxxxxxxx.ap-northeast-1.rds.amazonaws.com
のようなホスト名)をそのまま使用していました。
そのため、MySQLからAuroraに変更したときには接続情報を変えるためにRailsアプリケーションのデプロイが必要になってしまいます。
後述するようにDBの切り替え時にはダウンタイムが発生するため、できる限り手早く切り替える必要があります。 そのため、AWS Route 53でDB接続のためのプライベートホストを作成し、CNAMEにRDSが提供するエンドポイントを設定しました。 そして、Railsアプリケーションはこのプライベートホストへ向けて接続するようにします。
このようにすることで、DB切替時にはCNAMEの向き先を変更するだけでよくなり、比較的短時間でアプリケーションのDB接続先を切り替えることができるようになります。
Auroraレプリカの作成
まず既存MySQLにぶら下げる形で、AuroraのレプリカDBを作成しました。 この時点でDBクラスターを作成しておきます。
レプリカDBを作成したら、現在の認証情報でDBにログインできるか疎通確認を行います。
そこそこ大きいデータ量のDBですが、レプリカの作成は数時間で完了したと思います。
注意点1
弊社ではインフラリソースの管理はTerraformで行っています。そのためDBについてもリソースの設定をコードで表現する必要があります。
既存MySQLのインスタンスクラスがdb.m5
系だったので、何も考えずにAuroraレプリカもdb.m5
としたのですが、Auroraにはm5
系のインスタンスクラスがありませんでした。
Terraformを使用していると存在しないインスタンスクラスも指定することができてしまうため、Applyに失敗するまで気づくことができませんでした。
最終的に、弊社別プロダクトで利用実績があり、m5 と近しいスペックのr5 系を選定することにしました。
DB入れ替え
既存のMySQLを新しいAuroraを切り替えていきます。 この作業の間はプロダクトが使用できない状態(ダウンタイム)になります。 作業時間としては1時間程度を見積もっており、実際に30分程度で完了しました。
手順としては、次のようになります。
1.既存MySQLへの書き込みが0の状態にする。
ノマドクラウドのRailsアプリケーションはAWS ECSで動かしています。また、これら以外にDBに書き込む導線はありません。 そのため、ECSのタスクをすべて停止すればDBへの書き込みをなくすことができます。
実際に操作した作業としては、ECSのコンソールより必要なタスク数
というパラメータを0にしました。
2. レプリカとして動いているAuroraをプライマリに昇格させる。
RDSのコンソールよりAuroraのDBクラスター選択し、アクション
> 昇格
をクリックします。
この時点で、既存MySQLとAuroraのデータは同期されなくなります。
昇格は数分で完了しました。
3. DB接続用プライベートホストの向き先をAuroraに変更する
先ほど作成したDB接続用のプライベートホストの向き先をAuroraに変更します。 CNAMEのTTL設定によっては反映に時間がかかる恐れがあるため、事前に短い時間を設定するといいと思います。 今回はAmazon Route 53 DNS のベストプラクティスに記載されているTTLの最小である60秒を事前に設定していました。
4. 書き込みを元に戻す
1で設定したRailsアプリケーションのECSタスク数を元に戻します。
この時点で、プロダクトはダウンタイムから回復しました。 注意点として、古いMySQLとAuroraの間はデータ的に整合しない状態になったため、万が一なにかあった場合のロールバックが難しい状態になります。
5. CloudWatchアラームの無効化 (注意点2)
古いMySQLは書き込みがなく、接続数も0のままです。 アラームの設定によっては、この状態を異常と判断して発報する可能性があります。 不要になったアラームは忘れずに無効化しましょう。
検証環境で作業していたときに忘れており、手順が必要なことが発覚しました。
後片付け
不要になった古いMySQLを削除します。 また無効化したCloudWatchアラームなども併せて削除します。
注意点3
RDSのDBを削除する場合は、DBの設定で削除保護
を無効にしないと削除できません。
無効化する対応が漏れていて、Terraformでの削除適応時に少し手間取ってしまいました。
おわりに
イタンジではインフラリソースをTerraformを用いて管理していますが、DBの昇格といった特殊な作業はコンソールから作業したほうがわかりやすく、間違いも少ないと思います。(Terraformからできないことはないらしい)
データベースエンジンを変更するという割りと大掛かりな作業でしたが、事前に準備と手順をしっかり確認しておけば、ダウンタイム30分程度で切り替えができました。 次はAurora MySQLのバージョンを5.7から8.0にアップデートする作業を予定しているため、今回の経験を活かし事故なく完遂したいと思います。