Amazon RDSからAuroraへ Mackerelのデータベース移行で何が改善したか

こんにちは、MackerelチームでSREをしている id:heleeen です。

2023年3月に実施したMackerelのメンテナンスでは、データベースをAmazon RDSからAmazon Auroraに移行しました。この記事ではAuroraを選択した背景や、移行で考慮したことについてお伝えします。

データベースのアップグレードを機に検討

きっかけとしては、Mackerelで利用しているAmazon RDS for PostgreSQLのバージョンのサポート終了が近づいていたため、アップグレードする必要がありました。

その際、以前から気になっていたAmazon Aurora PostgreSQLへの移行を検討するよい機会だと感じたので、移行によりどのような変化やメリット・デメリットがあるのかを調査しました。その結果、Auroraへの移行は手軽に実施でき、今後の運用でメリットが多いと分かったので、移行を決めました。

なお、今回のアップグレードでAuroraに移行するかどうかを考え始めたのは計画外の行動でした。方針を決めるまでおよそ1週間しかないスケジュールでしたが、技術的な調査や検証と並行して、その短い期間で予算系の承認をもらうことができ、意思決定のスピード感がありがたかったです。

Auroraへ移行することによるメリット

パフォーマンスの改善

パフォーマンス観点では、一般的にRDSからAuroraへ移行することでパフォーマンスが改善すると言われています。

実際に本番サービスをAurora移行したところ、アプリケーションやクエリには特に変更を加えていないにもかかわらず、アプリケーションのレスポンスタイムが改善し、スロークエリがほぼなくなりました。

また、フェイルオーバーの検証を行ってみたところ、RDSに比べてダウンタイムが短く済むようになりました。

マイナーバージョンアップのダウンタイムが短く

当時は次のマイナーバージョンがなかったため検証はできていませんが、AuroraではPostgreSQLでもダウンタイムなしのパッチ適用が利用できるようになります。

条件を満たす必要があるため必ずしもダウンタイムがないことが保証されているわけではありませんが、今後はこのような機能を利用してダウンタイムの削減を考えていきます。

サイジングを適切にできリソース活用も効率的に

コストとしてはインスタンスタイプで比較すると、RDSに比べて割高にはなります。

一方で、ストレージはオートスケールされ、のちのアップデートでスケールインも可能になったため、より適切なサイジングが可能になります。これにより、ストレージを意識する運用も不要になりました。

とくにリードレプリカを利用する場合、RDSではプライマリのインスタンスに加えてリードレプリカを作成することになります。もしプライマリのインスタンスをマルチAZ構成とする場合、最低でもスタンバイを含めて3つのインスタンスが必要となります。読み取り可能なスタンバイDBインスタンスを持つマルチAZ DBクラスター配置もありますが、こちらも同様にインスタンスが3つ必要でした。

Auroraの場合は、Auroraのクラスタが作成されてそこに読み込み専用のエンドポイントがあるため、RDSのマルチAZ DBクラスター配置と同様に、レプリカを読み取りのスケールとして利用しつつマルチAZ構成にできますが、最低2つのインスタンスで構築できるという違いがあります。

もともと利用していたRDSのリードレプリカの負荷状況を確認したところ、Auroraに移行後のリードレプリカは1つでよいと判断できたため、インスタンス2つ分のコストで済ますことができました。インスタンスサイズによってはRDSよりコストを下げることができない場合もありますが、今回はインスタンス数を減らすことでコスト増加を抑えつつ、より効率的にリソースを活用できています。

リードレプリカの運用負荷も改善

リードレプリカで適切なインスタンス数を用意できることは、コスト面に加えて、運用面でのメリットもあります。例えば、RDSでメジャーバージョンのアップグレードを行う場合、プライマリのインスタンスとともにリードレプリカをあわせてアップグレードされるため、ダウンタイムが長くなるリスクがあります。

Mackerelチームではこれを避けるため、リードレプリカを事前に削除するという運用をしていました。しかし、この運用自体が負担であり、また事前に削除するためリードレプリカを参照する環境のダウンタイムが本来のRDSのダウンタイムより長くなる問題がありました。Auroraでは、このようなリードレプリカのアップグレード固有の運用を避けられるのも大きなメリットの1つです。

また、事前にAWSのSA(ソリューションアーキテクト)やRDSのスペシャリストに相談したところ、RDSに比べてAuroraの運用で特別留意しなければいけない点もなかったため、安心して移行に踏み切ることができました。

Auroraのリードレプリカを利用した移行

移行を選択できた理由として、RDSからAuroraへ移行する機能がAWSに揃っていることも挙げられます。移行の手段としていくつかの方法がありますが、今回は条件を満たせていることから、RDSにAuroraのリードレプリカを作成して昇格する方法を選択しました。

リードレプリカの作成は、実行してから完了するまでデータサイズに比例して時間がかかるため、アップグレード作業より少し前に実行しておく必要があります。自前でレプリケーションを組んでも同等のことは実施可能ですが、機能として用意されているため手軽に実行できるところがありがたかったです。

RDSにAuroraのリードレプリカを作成する

RDSからAuroraのリードレプリカを作成する場合、RDSのバージョンによっては、マイナーバージョンをアップグレードしたAuroraのリードレプリカを作成できます。このようにアップグレードと移行を同時に実施できることも、Auroraへ移行した大きな理由の1つです。一方で、マイナーバージョンが上がったことによる不具合が発生するリスクもあるため、リリースノートの確認や事前の検証によって問題ないことを確認しておくと、移行とアップグレードをより安全に実施できます。

Auroraのリードレプリカ作成にあたっては、クラスタに付与するDBクラスタパラメータグループと、インスタンスに付与するDBパラメータグループが必要です。これはRDSのパラメータグループとは別途用意する必要があります。また、AuroraとRDSでは設定できるパラメータが異なるため、RDSと全く同じには設定できないパラメータも存在します。

RDSからAuroraのリードレプリカの作成時のみ、この機能専用のレプリカクラスタが作成され、リードインスタンスのみのAuroraのクラスタが用意されます。このクラスタにはほかにインスタンスを作成できないため、Auroraクラスタで複数のインスタンスを立てる前に、昇格してクラスタを元のRDSから独立させる必要があります。

リードレプリカの昇格と切り替え

Auroraのリードレプリカ作成後、レプリケーション元のRDSとレプリケーション先のAuroraでレプリカラグが0になれば、リードレプリカを昇格させて、RDSから独立したAuroraのクラスタを作成できます。昇格できたら、アプリケーションで利用するデータベースをAuroraに切り替えることで、移行が完了します。

昇格前には、レプリカラグをなくすためRDSへの書き込みを止める必要があります。場合によっては、本番サービスを停止して昇格作業を行う必要があるでしょう。Mackerelではこれに該当していたため、本番サービスを停止メンテナンスに入れることにしました。

また、昇格してレプリケーションが切り離されたあとにレプリケーション元のRDSへ書き込みをしてしまうと、データの齟齬が出てしまう可能性があります。それを防ぐためにも、書き込み処理を停止しておく必要があります。

今回のメンテナンスでは追加の予防策として、データベースで実行されているクエリを監視して書き込みが停止していることを確認しつつ、昇格作業の前にRDSのセキュリティグループを変更して、アプリケーションからRDSへは接続できないようにしました。

Auroraのリードレプリカの昇格は、検証したところ2〜3分で完了することが分かりました。これは、データベースのデータ量によらずこの時間で実行完了したため、アップグレード作業の所要時間をより正確に計画できました。

なお、インプレースアップグレードの場合はアップグレードの所要時間が確定せず、昇格に比べると時間がかかってしまうため、それだけサービスの停止時間が長くなります。Auroraのリードレプリカを作成して昇格する方法であればアップデートも短時間で済むため、サービスの停止時間も短縮できました。

本番のAurora移行に向けて準備したこと

検証環境で移行して課題を確認

本番サービスの切り替えに向けた準備として、検証環境でRDSからAuroraへ移行してみて、Auroraリードレプリカの昇格で移行の手順に問題がないことや、Auroraでも問題なくアプリケーションが動作することを確認しました。

検証の結果としては、Auroraへの移行よりPostgreSQLのバージョンが上がることによる影響を中心に考慮しておくことで十分と感じられるほど、移行は簡単でした。

ただし、データは問題なく移行できたのですが、RDSとAuroraのパラメータの違いがあるため、多少のパフォーマンスチューニングは必要でした。具体的にはメモリ使用量が増加したため、パラメータを見直しています。これでメモリの使用傾向に変化がある可能性が事前に把握できたので、本番のキャパシティプランニングや移行後の経過観察ではメモリを中心に確認しました。

また、Mackerelで利用しているPostgreSQLの拡張機能については、Auroraへの移行やPostgreSQLのバージョンアップによって影響を受けるものではなかったため、拡張機能に関する調査や検証は軽く済みました。

こういった要因から、事前の検証を短期間で終えることができました。

本番メンテナンス時のバックアッププランを用意

事前の検証だけでなく、当日の作業でも問題なくAuroraへ切り替えができましたが、昇格が失敗したり、Auroraにすることで意図しない不具合が起きたりする可能性もありました。

今回のメンテナンスではバックアッププランとして、Auroraの昇格後にもとのRDSのスナップショットを作成して、復元し、そのインスタンスのバージョンを上げることで「バージョンアップしたRDS」という切り替え先を用意しました。

また、もとのRDSインスタンスそのものも、Aurora移行が失敗して、リストアしたRDSインスタンスのアップグレードも失敗した場合に切り戻す先として、そのまま残しています。

Mackerelのメンテナンス状態の切り替えを改善

今回のメンテナンスの計画を立てたところ、普段のRDSメンテナンスに比べてRDSに関連する操作の所要時間がかなり短くなる見込みとなっため、相対的にAurora移行以外の作業にかかる時間の割合が高くなることが気になっていました。

Aurora移行以外の作業のうち、Mackerelをサイトメンテナンス状態へ切り替える時間がかかることの課題感が大きかったので、今回はその切り替え手法も変更しました。

これまでサイトメンテナンスへの切り替えは、コンテナの再デプロイで行っており、デプロイによる待ち時間が発生していました。これをバックエンドが返却するレスポンスによってサイトメンテナンスかどうかを切り替えるように構成を変更しました。デプロイではなく設定変更で済むため、待ち時間はほぼなくなりました。

新しい切り替え手法の検証に取り掛かれたのが停止メンテナンスのおよそ1週間前で、完成したのも本番メンテナンスの数日前でしたが、本番で事故を起こすことなく迅速にメンテナンスを切り替えることができてよかったです。

この機能は今後の停止メンテナンスでも利用できるように実装したので、以前からの課題が1つ解消してよかったです。

まとめ

Auroraへの移行は、想像していたよりとても手軽に行うことができました。移行でより多くの機能を利用できるようになり、データベースの運用を改善できました。

一度安定的に運用されるようになったコンポーネントに大きめの変化を入れることで必要になったキャッチアップはありましたが、PostgreSQLと向き合う時間を作れたので楽しかったです。

今回はAuroraへの移行だったこともあり、サービスの停止時間をより短く抑えることができました。また、Mackerelをメンテナンスに切り替える手法も変更し、それも停止時間の短縮に効果的でした。

しかし、Mackerelのメンテナンスにはまだ課題があります。Blue/Greenでデータベースを切り替えられる構成にしたり、Auroraの機能を利用したり、アーキテクチャを変更したりするなど、今後もデータベースのメンテナンスによるサービス影響を少しでも減らす改善を続けていきます。

はてなでは、ともに改善を進めてくれるエンジニアを募集しています。

はてなでは、サービス開発の道標となるSREの仲間を募集しています