この記事はコインチェック株式会社のアドベントカレンダー9日目(シリーズ2)の記事です。
コインチェック株式会社のカレンダー | Advent Calendar 2024 - Qiita
はじめに
アプリケーション基盤部 SRE Gの萩原です。
この記事では、Coincheckサービスの主要なデータベースとして利用するAurora MySQLにおいて、2023年5月頃にリリースされたAmazon Aurora I/O-Optimizedの機能についてお話しします。
Amazon Aurora I/O-Optimizedとは?
Amazon Auroraで選択できる I/O-Optimizedとは、Aurora DB インスタンスとストレージ単価は従来の料金に対して高くなりますが、I/Oリクエスト数に応じた従量課金が発生しなくなることで、I/O負荷の高いワークロードの場合にコストを削減することができる機能です。具体的にはDBの費用に占めるI/Oの費用が25%を超える場合に料金パフォーマンスが良くなるようです。
Amazon Aurora I/O-Optimizedは、特にI/O操作に対する料金が発生しない点で注目されることが多く、コスト削減の側面から紹介されることが多い機能です。
しかし、こちらのリリース記事に記されているように「パフォーマンスは向上し、スループットは増加し、レイテンシーは減少します」という利点も見逃せません。Coincheckシステムではこのパフォーマンス向上の恩恵を得ることができましたので、本記事ではその詳細について紹介していきます。
CoincheckシステムにおいてAmazon Aurora I/O-Optimizedを利用するに至った背景
Coincheckシステムについて
コインチェック株式会社では「新しい価値交換を、もっと身近に」というミッションの元、暗号資産取引サービスCoincheckやCoincheck NFTと言った複数のサービスを提供しています。
数あるサービスの中でも「Coincheck 取引所」(板取引)はミッションクリティカルなシステムであり、板取引周りの処理についてのパフォーマンスは常に気にかけておく必要があるものとなっています。
Aurora MySQLのアップグレードの事前負荷テストでAurora MySQL 3のパフォーマンスが悪い
Coincheckシステムで利用するDBはAurora MySQLであり、2024年10月31日にAurora MySQL 2がEOLを迎えるにあたり、2 → 3にバージョンを上げる必要がありました。アップグレードにより板取引周辺の処理パフォーマンスが劣化することは許されないため、負荷テストを実施することで性能評価を行いました。評価結果は、Aurora MySQL 2と比較してAurora MySQL 3のCommit( = 待機イベントのwait/io/aurora_redo_log_flush)が遅くなることで、板取引周辺の処理全体のパフォーマンスが劣化する結果となりました。
該当のアプリケーション処理は既に改善を重ねてきており、アップグレードを実施するまでの期間でさらに処理を改善することは難しいと考えていました。そのためAurora MySQLのパラメータ変更でなんとかできないかを模索しましたが、Commit周りを改善するものとしては、innodb_flush_log_at_trx_commit という設定によってデータ損失の可能性があるパラメータくらいしか調整の余地がなく、利用者側で調整できるパラメータがかなり少ないことがわかりました。これ以外でもAurora MySQLのマイナーバージョンの変更やインスタンスタイプ変更などインフラ的な観点での変更も試しましたが、どれもAurora MySQL 2と同程度のパフォーマンスを出すにはいたりませんでした。
そんな中、AWS サポートに相談したところ、Aurora I/O-Optimizedの案内をいただきました。筆者も案内を受けた当初は、Aurora I/O-Optimizedはパフォーマンスを向上させる可能性があるという認識がなく、コスト削減の文脈で利用する設定と考えておりました。
Amazon Aurora I/O-Optimizedの負荷テスト結果
結論、Amazon Aurora I/O-Optimizedを利用することで、Aurora MySQLのバージョン3でバージョン2よりもパフォーマンスとしては良い結果が出ることとなったのですが、どのような結果となったのか見ていこうと思います。
負荷テストの前提条件
以下のツールや環境で負荷テストを実施しました。負荷テストにおいて、使用するツールや設定、環境は非常に重要な要素です。しかし、本記事の主題からは外れるため、詳細な説明は割愛させていただきます。
-
負荷テストツール
-
ツール
flood.io(※) -
実行時の仮想ユーザ数
以下を2つの変数を掛け算することで算出します。-
Node数( = シナリオを書いたスクリプトを実行するマシンの台数): 一律5台
-
スレッド数( = Node毎のユーザ数): 15, 27, 50でシナリオを実行
-
-
1回あたりの実行時間
15分
-
-
テスト環境
-
テストに利用したAurora MySQLのバージョンと設定
-
Aurora MySQL 2系: 2.12.0
-
Aurora MySQL 3系: 3.04.1、StorageType: Aurora Standard
-
Aurora MySQL 3系: 3.04.1、StorageType: Aurora I/O-Optimized
-
-
DBの構成
-
台数: Writer/Reader それぞれ1台ずつの計2台
-
インスタンスタイプ: db.r5.24xlarge
-
-
その他
-
アプリケーションサーバが動作するインフラ構成については、テスト実行ごとで変更することはせず、基本的には同じ条件でテストを実施
-
-
※ flood.ioは2024年6月でサービス終了となっており、現在ではGatling Enterpriseを利用しています
テスト結果
以下メトリクスについて、負荷テスト時の値を確認します。本記事では結果を分かりやすく確認できるように以下メトリクスに絞っておりますが、実際はこれ以外のDB周りのメトリクスやAPM、その他独自に計測しているメトリクスを確認しております。
-
秒間あたりのクエリ実行数の平均
数の多い方がSQLが多くDBで実行されており、パフォーマンスが良いことを表します。 -
秒間あたりのCommit Throughputの平均
数の多い方が秒間あたりのコミットの実行数が多く、パフォーマンスが良いことを表します。 -
Commit Latencyの平均時間
数の少ない方がコミットあたりの時間が短く、パフォーマンスが良いことを表します。 -
wait/io/aurora_redo_log_flush のAverage active session
数の少ない方がパフォーマンスが良いことを表します。
Performance Insightsで簡単に確認できる指標で、このイベントは、セッションが永続データを Aurora ストレージに書き込むときに発生します。
参考: https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/ams-waits.io-redologflush.html
テスト毎に一番良いパフォーマンス結果を赤字にしています。
結論
テスト実施箇所に関しては、Aurora MySQL 2.12.0と比較してAurora Standardの設定の3.04.1では性能が劣化していますが、I/O-Optimizedとすることで、大幅に性能が向上することがわかりました。特に負荷( = 仮想ユーザ数)が上がるほど、差は顕著になっていきます。
テストの結果、Aurora MySQL 3をI/O-Optimizedに設定することで、パフォーマンス上は問題ないことが確認でき、無事にAurora MySQL 2 → 3へのアップグレードを実施することができました。あくまでCoincheckシステムの処理における検証結果であるため、もちろん一概にパフォーマンスが向上するとは言えません。しかし、コスト削減に焦点が当たることが多いAmazon Aurora I/O-Optimizedで、このようにCommit周りのパフォーマンスが向上する可能性もあり、もし同じような境遇の方がいらっしゃった場合に参考にしていただければ幸いです。
Amazon Aurora I/O-Optimizedの注意点
その他、実際にAurora I/O-Optimized設定のDB Clusterを運用する際にいくつか注意点がありましたのでまとめました。
-
オンデマンドインスタンスの料金が30%増し、Storage利用料も125%増しになる。また、Aurora I/O-Optimizedでの料金の増分もRIの割引対象となるが、正規化係数という概念を用いて購入するインスタンスサイズを計算する必要がある
料金について: - 既存のデータベースクラスターを Aurora I/O-Optimized に切り替えることができるのは、30 日ごとに 1 回で、Aurora Standard にはいつでも戻すことができる
-
既に Aurora I/O-Optimizedが設定されたクラスターからRestoreDBClusterToPointInTimeを実行してクラスターをクローンをする際、StorageTypeをデフォルトの Aurora Standardとしたい場合、StorageType = auroraを明示的に設定しないとAurora I/O-Optimizedの設定で建ち上がってしまう
-
定期的にクローンを実行するバッチなどを組んでおり、クローン先のClusterではAurora Standardで利用したい場合は注意が必要です。
-
-
パラレルクエリが利用できない
Amazon Aurora 向けリザーブド DB インスタンス - Amazon Aurora
-
2024年12月現在、パラレルクエリを利用する際はバッファプールが利用されず、全てストレージレイヤーからデータを読み込んでくるため、IO料金が高くなりがち
-
I/O-Optimizedの設定でパラレルクエリが利用できるようになれば最強
-
おわりに
Amazon Aurora I/O-Optimizedの機能や、Coincheckシステムで利用するAurora MySQLにおいて利用するに至った経緯、またその性能について書かせていただきました。
単純なコスト削減のみならずI/O周り、Coincheckシステムでは主にCommitのパフォーマンスを向上させることができました。
ここまで本記事をお読みいただきありがとうございました。この記事が皆様のお役に立てば幸いです。
今後も皆様にとって有益な情報を提供できるよう努力してまいりますので、引き続きどうぞよろしくお願いいたします。