概要
こんにちは、スタンバイで求人の取り込みシステムの開発・運用を担当している池田です。
スタンバイでは、求人データのマスターデータ管理に Aurora MySQL を使用しています。 運用開始から3年以上が経過し、その間にシステムは成長を続けてきましたが、それに伴いコストも徐々に増加していました。特に2024年は円高の影響も相まって、Aurora MySQL のインフラコストは、ますます大きな課題となりました。
実は2023年にも、Aurora MySQLのコスト削減を目指し、多くのRead操作をDynamoDBに移行することで、大幅な削減に成功しました(詳しくはこちらの記事をご覧ください)。その時に55%のコスト削減を達成しましたが、2024年もさらなる最適化に挑戦しました!
今回のブログでは、2024年に行ったAurora MySQLのコスト最適化の取り組みと、どのようにしてさらに54%の削減を達成したのか、その詳細をご紹介します。
実施した施策と結果
まず先に結果からですが、2024年3月と2024年8月を比較した結果Aurora MySQLのインフラコストを約54%削減できました。
今回実施した施策と、その削減割合の内訳は以下の通りです。
番号 | 施策案 | 削減割合 |
---|---|---|
① | Auroraクラスターのレプリカの台数を減らし、インスタンスタイプを下げる | 9.6 %削減 |
② | Auroraクラスターの再構築により、肥大化した MySQL の ibdata1 を削除 | 30.5 %削減 |
③ | リザーブド DB インスタンスの購入 | 14.1 %削減 |
以下では、それぞれの施策について詳しく説明します。
① Auroraクラスターのレプリカ台数を減らし、インスタンスタイプを下げる
コスト最適化の前は、Auroraクラスターは6台のレプリカを使用していました。
レプリカのメトリクスを分析したところ、CPU使用率に十分な余裕があることが判明しました。これは、以前実施した対応や、過去1年にわたる仕様変更などによって、レプリカへの負荷が軽減されたためだと考えられます。そこで、レプリカ台数の削減とインスタンスタイプの変更について検討しました。
ただし、コスト削減を実施する際、パフォーマンスに悪影響が出ないようにすることが最も重要です。そのため、処理負荷のピーク時でもCPU使用率が60%を超えない範囲で、段階的にインスタンスタイプの変更とレプリカ台数の削減を進めました。
具体的には、負荷試験を事前に実施し、インスタンスの変更を段階的に行い、その都度状況を観察しました。詳細なインスタンスタイプは非公開ですが、レプリカ数を6台から5台に減らし、インスタンスタイプを一段階下げることで、約9.6% のコスト削減を達成しました。
Auroraクラスター全体では9.6%の削減ですが、レプリカインスタンスに関しては、変更前のインスタンス費用の約半分まで削減できました。
なお、今回対象としているAurora MySQLは、write-heavyなアプリケーションであり、メトリクスを確認したところ、プライマリインスタンスにはコスト削減の余地がほとんどないと判断しました。 そのため、プライマリのインスタンスタイプは据え置くことにしました。
② Auroraクラスターの再構築により、肥大化した MySQL の ibdata1 を削除
今回の施策の中でも、最も時間がかかった施策がこの「Auroraクラスターの再構築」です。
AuroraのCostExploreを確認すると、Auroraのストレージ料金であるAurora:StorageUsageという指標があります。
このAurora:StorageUsage は Auroraが使用しているストレージ容量を示す指標で、実データやインデックスだけでなく、InnoDBテーブルのメタデータやバッファ、UNDOログなどのシステムデータも含まれています。
これらの管理データは、MySQLのInnoDBストレージエンジンによってibdata1というファイルに格納されています。このibdata1ファイルは、以下のクエリで確認できます。
mysql> SELECT file_name,tablespace_name,engine,ROUND(SUM(total_extents * extent_size) / (1024 * 1024 * 1024 * 1024), 2) AS "TableSizeinTB" FROM information_schema.FILES WHERE file_name LIKE '%ibdata%'; +-----------+-----------------+--------+---------------+ | file_name | tablespace_name | engine | TableSizeinTB | +-----------+-----------------+--------+---------------+ | ./ibdata1 | innodb_system | InnoDB | 59.87 | +-----------+-----------------+--------+---------------+ 1 row in set (0.03 sec)
ストレージに占める割合を調査した結果、ibdata1ファイルはAuroraが使用しているストレージ容量の 99.97% を占めていることがわかりました。
長期間にわたり、スタンバイの求人データを管理してきた結果、ibdata1は非常に肥大化していたのです。
ストレージ容量削減のために不要なテーブルやレコードを削除しましたが、ibdata1 はデータを削除してもサイズが減少しないため、根本的な解決には一度Auroraクラスターを再構築する必要がありました。
ただし、物理バックアップ(DB クラスタースナップショット等)ではibdata1も含めて全データが復元されてしまうため、ストレージ削減の効果はありません。そこで、論理バックアップ を使用して移行する必要がありました。しかし、テーブル数やレコード数が非常に多いため、物理バックアップに比べて時間がかかることが懸念されました。
いくつかの検証をした結果、AWS Database Migration Service(DMS)を使用することで、ダウンタイムを最小限に抑えながらデータ移行を進められることがわかりました。1
AWS DMS を利用する上で、工夫したこと
AWS DMSは、ダウンタイムを最小限に抑えながらデータを移行できるマネージドサービスであり、MySQLを含む多くのデータベースに対応しています。
まず、DBをサービスインしたまま移行できるか が最初の課題でした。これが可能であれば、ほぼダウンタイムなしでデータ移行が完了します。しかし、DMSを使用して検証をしたところ、フルロード完了後、レプリケーション遅延が広がり続ける問題が発生しました。
DMSは、Aurora MySQLのバイナリログを読み取ることで変更をキャプチャしますが、今回のように更新頻度が非常に高いシステムでは、CDCソースレイテンシー(変更データキャプチャの遅延)が発生し、レプリケーションが追いつかなくなるという問題に直面しました。
▲上記のキャプションで何度かCDCソースレイテンシーが下がっていますが、これは再度フルロードをやり直したためになります。
そこで、レプリケーションを行わず、Aurora MySQLのマスター更新を一時停止してDMSのフルロードを実行する方針に変更しました。検証の結果、マスター更新を停止した状態でのフルロードは約4時間で完了することが確認され、更新停止時間は許容範囲内に抑えられる見込みが立ちました。
最終的には社内で調整し、マスター更新を約4時間停止することで、無事DMSによるフルロード1回で再構を完了させました。
Aurora MySQL クラスター再構築の結果と効果
ibdata1のサイズを大幅に削減した結果、Aurora:StorageUsageのコストは 97.7% 削減されました。
さらに、次のような副次的効果も得られ、スタンバイのシステム全体に対して大きな改善が見られました。
- Aurora MySQLのクエリレイテンシーが改善
- Aurora MySQLに接続するAPIの応答速度も向上しました。
- Aurora MySQLのバックアップ費用が97%低下
- 毎日バックアップを取得しているため、このコスト削減効果は非常に大きいです。
さらに、ibdata1 と直接的な因果関係がないのですが、Aurora:StorageIOUsage のコストも3月と比較して33%下がっておりました。(Aurora MySQLの削減割合で13.35% 削減)
明確な因果関係はわかっていないのですが、StorageUsageが下がったことに加え、インスタンス台数を減らしたことや、Aurora MySQLのメジャーバージョンをあげたことなどが影響しているかもしれません。
Aurora MySQL クラスター再構築の施策により、StorageUsage, StorageIOUsage, BackupUsageのインフラ費用が削減され、合計で3月のAuroraの費用から 30.5% のコスト削減に成功しました。
またこの施策以降、アプリケーションコードから不要なトランザクション処理を削除し、ibdata1が肥大化する速度を大幅に落としました。
③リザーブド DB インスタンスの購入
最後に行った施策は、リザーブド DB インスタンスの購入です。
Amazon Aurora のリザーブド DB インスタンスは、1 年間または 3 年間の契約で特定のインスタンスタイプとリージョンを指定してインスタンスの予約購入することで、オンデマンドの DB インスタンスに比べて大幅な割引が適用されるプランです。
詳しくは、Amazon Aurora 向けリザーブド DB インスタンスに記載されています。
リザーブドインスタンスは購入後にインスタンスタイプ、リージョン、期間の変更は不可となるため慎重さが求められます。複数メンバーで今後のAurora MySQLのキャパシティ予測を確認しながら購入するプランの検討を進めました。 また、支払い方法(「全額前払い」、「一部前払い」、「前払いなし」)によっても少し割引率が変わってくるため、支払い方法も含めて社内各所に確認と相談をし、購入を完了させました。 この施策によって全体の 14.1% のコスト削減を実現しました。
施策のまとめ
今回の記事で取り上げたこと以外にもいくつかコスト削減施策を実施しましたが、AWSのCost Explorerを活用して仮説を立て、それに基づいた施策の立案、検証、実施を進めることで大幅なコスト削減を達成できました。特に、長期間運用されていたAurora MySQLを再構築し、不要なトランザクション処理を見直すことで、大きなコスト削減を実現できたことが印象的でした。 また、Auroraクラスターの再構築によって、単にコスト削減だけでなく、DBクエリのレイテンシー改善やAPI応答速度の向上といった副次的な効果も得られました。
最後に
2023年にAurora MySQLのインフラコストを55%削減できましたが、今回の取り組みでさらにコストを54%削減し、最終的にAurora MySQLのインフラコストが約1/5にまで下がりました。 (逆に言えば、昨年までのコストは現在の5倍もかかっていたということです。)
コスト最適化は一度実施して終わりではなく、継続的に取り組むべきもの であると、改めて実感しました。そのため定期的にCost Explorerを確認し、分析することが重要かと思います。
スタンバイのプロダクトや組織について詳しく知りたい方は、気軽にご相談ください。 www.wantedly.com
- 論理バックアップの案として、Aurora MySQL への書き込みを停止し、mysqldump でデータをエクスポートし、新規作成した Aurora MySQL クラスターにインポートして再構築する方法も検討しました。しかし、この方法では停止時間が2日以上かかる見込みであったため、不採用としました。↩