Amazon Web Services ブログ

Amazon ElastiCache を使用して RDS for MySQL ワークロードのコストを最適化し、パフォーマンスを向上させる

データ量とユーザー数が増えるにつれて、アプリケーションのパフォーマンスと応答時間を改善する一方で、データベースのコストを最適化しなければならないという課題に直面することがよくあります。大量のデータとスループットを持つインターネット規模のアプリケーションには、マイクロ秒単位のレイテンシーをサポートできる基盤となるデータアーキテクチャが必要です。アプリケーションのパフォーマンスを向上させることで、お客様は応答時間を短縮し、外部および内部のユーザーにより良いサービスを提供できるようになります。インメモリキャッシュは、アプリケーションのパフォーマンスを向上させると同時に、お客様が費用対効果の高い方法でビジネスを成長させ、市場を拡大できるようにします。

データベースに分散結果セットキャッシュを追加することは、アプリケーションのパフォーマンスを向上させ、コストを削減するための一般的な方法です。 Grab、Wiz、DBS Bank は、Amazon ElastiCache for Redis をプライマリデータソースと組み合わせて使用し、リアルタイムアプリケーションのパフォーマンスニーズをコスト効率よく実現している多くのお客様の一例です。ElastiCacheはフルマネージド型のRedis互換のサービスで、最新のアプリケーションにリアルタイムで最適化されたパフォーマンスを提供します。ElastiCacheは、マイクロ秒の応答時間で毎秒数億オペレーションまでスケールし、エンタープライズグレードのセキュリティと信頼性を提供します。お客様はElastiCacheを、アプリケーションやデータベースのパフォーマンスを高速化するため、あるいはデータの耐久性を必要としないユースケース(例えばセッションストア、ゲームリーダーボード、ストリーミング、データ分析、ML推論用のフィーチャストアなど)のプライマリデータストアとして使用しています。このブログ記事では、Amazon ElastiCache をクエリキャッシュとして利用することでリレーショナルデータベースのコストを最適化する方法を解説します。ここで使用されたデータは、インスタンスタイプdb.r6g.xlargeのAmazon RDS for MySQLバージョン8.0.28で実行したベンチマークテストに基づいています。ベンチマークテストでは、Amazon ElastiCacheでクエリ結果をキャッシュしています。

Amazon ElastiCache for Redis

Amazon ElastiCache は AWS が提供する目的別キャッシュサービスです。 ElastiCache はプライマリデータソースを補完し、わずかなコストで全体的なパフォーマンスを最適化し、迅速なスケーリングを可能にします。

ElastiCache は、次のような機能を備えたフルマネージド型の AWS サービスです。

  • 非常に高速 — ミリ秒未満の応答時間でインメモリキャッシュとして機能します。
  • ワークロードのニーズに合わせて、中断することなく垂直方向と水平方向の両方に拡張できます。
  • エンジンのマイナーバージョンアップを含む、ハードウェアとソフトウェアの管理をフルマネージドで行えます。 サービス中断時の自動フェイルオーバーや自動インスタンス復旧など、マルチ AZ 機能により高い可用性を実現しています。 さまざまなワークロードに対応する自動スケーリング機能を備え、データ階層化やリザーブドインスタンスタイプもサポートしています。
  • オープンソースの Redis と互換性があります。

Amazon ElastiCache によるAmazon RDS for MySQLのコスト最適化

Oracle、SQL Server、Amazon RDS などのリレーショナルデータベースにキャッシュソリューションとして ElastiCache を実装すると、アプリケーションのパフォーマンスを向上させ、コストを削減することができます。ElastiCache を RDS for MySQL と組み合わせて使用することにより、RDS for MySQL を単独で利用した場合と比較して、コストを最大 55% 節約し、読み取りパフォーマンスを最大 80 倍高速化することができます。

ElastiCache は結果セットをキャッシュし、データベース I/O をオフロードすることで、コストを削減し、データベースとアプリケーションの両方のパフォーマンスを向上させることができます。 プライマリデータソースの前にキャッシュレイヤーを追加する方が、データベースインスタンスのキャパシティを大きくするよりも費用対効果が高くなります。 1 つの ElastiCache ノードは 1 秒あたり 250,000 件を超えるリクエストを処理できます。 同じ結果セットを返す共通のデータベースクエリを使用する読み取り負荷の高いワークロードでは、クエリ結果をキャッシュすることで大きなメリットが得られます。 一方、すべてのデータベースワークロードでキャッシュサービスを追加してもメリットがあるわけではありません。ほとんどのトランザクションが挿入または更新である書き込み負荷の高いデータベースは適していません。ストアドプロシージャやトリガーによるカスケードアップデートのようなデータベースレベルの処理を必要とするアプリケーションも、キャッシュの恩恵を受けません。 ElastiCache は、以下のようなアプリケーションによく適合します。

  1. 大量のスループットを処理する必要があるアプリケーション
  2. 短い間隔でトラフィックピークが増加するようなアプリケーション
  3. データベース更新の前にメモリ内の大量のデータをリアルタイムで処理して統合するアプリケーション
  4. 即時のユーザー応答をサポートする必要があるアプリケーション

ElastiCache + プライマリデータソース

ElastiCache は、MySQL、Oracle、PostgreSQL、SQL Server などのリレーショナルデータベースや、Amazon DynamoDBAmazon DocumentDB (with MongoDB compatibility) などの NoSQL データベース、Amazon Simple Storage Service (Amazon S3)で使用できます。また、マイクロサービス間のようなデータベース層でなくても使用できます。

ElastiCache + プライマリデータソース

図 1 — Amazon ElastiCache により、様々なデータソースをキャッシュ

ElastiCache により、リードレプリカの使用量を削減し、コストを節約する

下の図では、RDS for MySQLリードレプリカをElastiCache クラスターの読み取りキャパシティに置き換えました。分散された ElastiCache クラスターを追加する方が、リードレプリカを追加するよりもコストがかかりません。同等のレベルの読み込みキャパシティを低コストで実現でき、パフォーマンスも向上します。キャッシュは専用のメモリ、ネットワーク、CPU を提供するため、レイテンシーが大幅に改善し、スループットが大幅に向上します。 ここでデータベースの全てのデータをキャッシュに複製しているわけではないことを覚えておく必要があります。 キャッシュする必要があるのはクエリの結果だけなので、データベースを完全に複製する必要はありません。

ElastiCache により、リードレプリカの使用量を削減し、コストを節約する

図 2 — Amazon ElastiCache を利用して、RDS レプリカの必要量を減らす

キャッシュ — アプリケーション実装戦略

以下は、データをキャッシュするためにアプリケーション実装戦略です。

レイジーロードキャッシュ

レイジーロード戦略は、レイジーポピュレーションまたはキャッシュアサイド戦略とも呼ばれ、お客様に最もよく利用されているキャッシュ戦略です。 基本的な考え方は、アプリケーションが実際にオブジェクトを要求したときにのみキャッシュにデータを入力することです。 全体的なアプリケーションフローは次のようになります。

  1. 例えば最新のニュース記事の上位10件など、アプリケーションがクエリを受け取ります。
  2. アプリケーションはキャッシュをチェックし、オブジェクトがキャッシュ内にあるかどうかを確認します。 その場合 (キャッシュヒット)、キャッシュされたオブジェクトが返され、コールフローが終了します。
  3. そうでない場合 (キャッシュミス)、データベースにオブジェクトを問い合わせます。
  4. データベースからロードされたデータは、次回のためにキャッシュに入力され、クエリの結果としてオブジェクトが返されます。
レイジーロードキャッシュ

図 3 — レイジーロードまたはキャッシュアサイド戦略

ライトスルーキャッシュ

一貫性を必要とするワークロードでは、ソースデータストア内のデータが変更されたときに、ライトスルー戦略を使用してキャッシュを更新できます。 ライトスルーでは、ソースデータストアの更新時に変更を検出しキャッシュを更新するメカニズムか、データが変更されたときにお客様がキャッシュとソースの両方に二重書き込みプロセスを実装することが必要です。 ライトスルーを実装するクライアントアプリケーションはデータベースを更新し、書き込みが成功するとデータベースからデータを読み取り、新しいクエリ結果を同期的にキャッシュします。

ライトスルーキャッシュ

図 4 — ライトスルー戦略

アプリケーションは Redis クライアント API を介して ElastiCache で構成されるキャッシュレイヤーを呼び出します。 レイジーロード戦略はデータをキャッシュに読み込むのに役立ちますが、その主な目的は、データが存在する場合にプライマリデータソースにアクセスせずキャッシュからデータを読み取ることです。 ライトスルー戦略はデータをデータベースと同期させるのに役立ちますが、一般的にはレイジーローディング戦略とライトスルー戦略の両方を実装し、データが存在する場合はキャッシュから読み取り、キャッシュに書き込んでデータを最新の状態に保ちます。 ElastiCache for Redis のキャッシュ戦略の詳細については、こちらを参照してください。

RDS for MySQL + ElastiCache – Better Together の例

読み取りと書き込みの比率が80:20で、読み取られたデータの 80% がキャッシュされている場合

キャッシュのパフォーマンス上の利点、コスト上の利点、アプリケーション実装戦略について説明したところで、コスト削減とパフォーマンス向上の例を見てみましょう。 30,000 クエリ/秒 (QPS) のスループットを実現する必要があるとしましょう。 この要件を満たすには、RDS for MySQL のリードレプリカを利用する方法と、RDS + ElastiCache を利用する方法があります。 ElastiCache を利用せずに RDS だけを利用する場合、スループット要件を満たすには RDSの リードレプリカが 4 つ必要になり、そのコストは 1 か月あたり 1,740 USD (db.r6g.xlarge)になります。 RDS + ElastiCache を使用する場合、リードレプリカを排除し、代わりに 1 つの ElastiCache ノードとそのリードレプリカノードで同じスループットを実現できます。 RDSのリードレプリカの代わりに ElastiCache を利用すると、1 か月あたり 780 USD の費用がかかります。 ElastiCache と RDS のコストは、リードレプリカに RDS だけを使用する場合と比べて 55% のコスト削減につながります。 以下の表は、使用するノードとそのコストの詳細を示しています。

メトリクス RDS
プライマリのみ
RDS プライマリ
+ リードレプリカ
RDS プライマリ
+ 4 リードレプリカ
RDS プライマリ
+ 2 ElastiCache node
平均待機時間 200 ミリ秒 80 ミリ秒 80 ミリ秒 1 ミリ秒
平均読取QPS 8,000 QPS 16,000 QPS 30,000 QPS 32,000 QPS
コスト $/月 348 $/月 696 $/月 1,740 $/月 780 $/月
使用ノード 1 read/write
db.r6g.xlarge
1 writer 1 reader =
2x db.r6g.xlarge
1 writer 4 reader =
5x db.r6g.xlarge
1x db.r6g.xlarge +
2x cache.m6g.xlarge

RDS for MySQLの設定とデータベースサイズ:
データセットサイズ:~80GB
ストレージ:300GB
RDS ノード:MySQL version 8.0.28, db.r6g.xlarge
テストSQL:

SELECT firstname, lastname, from_airport FROM booking WHERE passenger_id = <passenger id>

より高いスループットでのコスト削減 – 100% のデータをキャッシュし、さらなるコスト削減を行う

キャッシュを実装すると、アプリケーションのスループット要件が高ければ高いほど、コスト削減効果も大きくなります。 以下の例では、キャッシュが完全にウォームアップされる (つまり、読み取られるすべてのデータが ElastiCache によって処理される)と、読み取り容量は 250,000 QPS に達します。RDS だけでは、このスループットをサポートするコストは 87% 高くなります。 スループットの高い、読み取り量の多いアプリケーションにキャッシュを実装することで、コストを大幅に削減できます。

メトリクス 1 RDS + 9 RDS read replicas 1 RDS + 1 RDS read replica
+ 1 ElastiCache + 1 EC read replica
平均待機時間 80 ms 9 ms
平均読取QPS 250,000 250,000
コスト $/月 7,840 $/月 784 $ (RDS) + 432 $ (EC) /月
使用ノード 10 x db.r6g.xlarge 2 x db.r6g.xlarge + 2 x cache.m6g.xlarge

結論

RDS などのプライマリリレーショナルデータベースに ElastiCache を実装することで得られるコスト削減は、アプリケーションに必要な読み取りスループットに比例します。 必要な読み取りスループットが高ければ高いほど、コスト削減量も大きくなります。 これは、スループットが増加するにつれて、リレーショナルデータベースのスケーリングにかかるコストが高くなるためです。 一方、各 ElastiCache ノードは 1 秒あたり最大 400,000 件(*1)のクエリのスループットをサポートできます。 ElastiCache をアプリケーションアーキテクチャに追加することで、パフォーマンスを向上させ、コストを削減できます。
(*1 訳注:Amazon ElastiCache for Redis 7.1の登場により、さらに最大スループットが向上しました。例えばr7g.4xlargeを用いたテストではRedis 7.0と比較してスループットが100%以上向上し、1 秒あたり1,000,000 件以上のリクエストを処理しました。詳細はこちらのブログをご覧下さい)

Amazon ElastiCache を使い始めるには、入門ガイド自習型学習コース、またはオンデマンド学習パスを参照してください。 Amazon ElastiCache 製品ページにアクセスして、その他のリソースを検索したり、詳細を確認したりすることもできます。 より詳細なガイダンスについては、AWS アカウントチームに連絡して Amazon ElastiCache スペシャリストによる詳細なセッションをスケジュールしてください。

このブログで説明されているキャッシュ戦略を実装するサンプルコードを Github リポジトリからダウンロードすることもできます。


本記事は、Sashi Varanasi, Steven Hancz, Roberto Luna Rojas らの「Optimize cost and boost performance of RDS for MySQL using Amazon ElastiCache for Redis」を翻訳したものです。翻訳は ソリューションアーキテクトの 堤 勇人が担当しました。