リードレプリカを活用してRDSの負荷分散を実際に検証してみた。
目次[非表示]
- 1.はじめに
- 2.まず、データーベースの「負荷分散」って何でしょうか?
- 3.RDSとリードレプリカとは
- 4.ここからは実際にテストしてみました
- 4.1.RDSでデーターベースを作成
- 4.2.テストデータを作成
- 4.2.1.railsアプリケーションの設定
- 4.3.データーベースにテストデータを追加する
- 4.3.1.テストデータをコマンドで追加
- 4.3.2.テストデータがRDS(MySQL)に入っているか確認する
- 4.4.RDSからリードレプリカを作成
- 4.5.テストツール(JMeter)のセットアップ
- 4.5.1.JMeterのインストール
- 4.5.2.JMeterテストプランの設定
- 4.5.2.1.スレッドグループを作成
- 4.5.3.JDBC接続設定追加の設定
- 4.5.4.JDBCリクエストの設定
- 4.5.5.リスナーの指定
- 4.6.テスト結果の比較
- 5.終わりに
はじめに
こんにちは、株式会社divxエンジニアの木村です。
今回のブログでは、データベースの負荷分散についての検証を行いました。
具体的には、Amazon RDSにリードレプリカを導入することで、どれだけの負荷分散効果があるのかを実際にテストしてみました。
まず、データーベースの「負荷分散」って何でしょうか?
そもそもデータベースに負荷がかかる状況とは、たとえば、
・多数のユーザーから同時にアクセスがある時
・大量のデータを一度に処理する時
などが考えられます。これらの負荷を一つのサーバーだけでなく、複数のサーバーに分散させることで、
処理能力を向上させたり、システムが停止するリスクを減らすことができます。
RDSとリードレプリカとは
まずRDSとは??chatGPTに聞いてみました。
AWSが提供するクラウド上でのリレーショナルデータベースのサービスです。手間のかかるデータベースの運用や管理作業を簡単にするためのツールが備わっています。
そしてリードレプリカについても聞いてみました。
リードレプリカとは、データベースの主要なインスタンス(マスター)のコピーを作成して読み取り専用の複製サーバー(レプリカ)を作成します。読み取りクエリの負荷を分散するためのもので、大量の読み取りアクセスがある際に性能を向上させることができます。
これらの情報を元に、実際にRDSからリードレプリカを作成し、その性能をテストしてみました!
ここからは実際にテストしてみました
AWSの環境を使用して、RDSのリードレプリカの構築と性能検証を行いました。
・通常のRDSのみを使用する場面
・RDSとリードレプリカを併用する場面
テストまでの手順は次の通りです。
- RDSでデーターベースを作成
- テストデータを作成
- データーベースにテストデータを追加
- データの入ったRDSからリードレプリカを作成
- テストツール(Jmeter)のセットアップ
- Jmeterにてテスト実行
- テスト結果の比較
RDSでデーターベースを作成
RDSのコンソールからデーターベースを作成します。
今回は以下の設定でデーターベースを作成しました。
・データーベースの種類 : MySQL
・マスターユーザー名を設定(後の設定で使用)
・マスターパスワードを設定(後の設定で使用)
・パブリックアクセスの変更
⚪︎デフォルトは「拒否」に設定されており、VPC内からのアクセスのみ 許可される状態
⚪︎今回はローカル環境からのDB接続を必要としたため「許可」に変更
⚪︎ただ、セキュリティ上、この設定は推奨されないため注意が必要
⚪︎追加設定にてDB名を設定 (後の設定で使用)
データーベース作成後、「利用可能」のステータスになるまで数分かかります。
テストデータを作成
railsアプリケーションの設定
・ローカル環境にてrailsのアプリケーションを作成する
⚪︎rails new アプリ名
・Railsのconfig/database.ymlにRDSの接続情報を設定
⚪︎RDSの情報とリードレプリカの情報を記述 (RDS データーベース 接続とセキュリティで閲覧可能)
config/database.yml
・ユーザーデータをdb/seeds.rbに記述する
⚪︎Faker gemを使用して10,000件のランダムなユーザーデータを生成
db/seeds.rb これで1万件のユーザーデータがローカル環境にて作成できました!
この後はこのデータをRDSに追加していきます。
データーベースにテストデータを追加する
テストデータをコマンドで追加
・アプリケーションのルートディレクトリでrails db:seedコマンドを実行
⚪︎このコマンドで、db/seeds.rbファイルに記述されたロジックを実行し、RDSにテストデータを追加できる。
テストデータを追加するのは結構時間かかりました(10分ぐらい)
テストデータがRDS(MySQL)に入っているか確認する
・アプリケーションのルートディレクトリでrails db:consoleコマンドを 実行しMySQLを起動
・SELECT * FROM users;を実行しusersテーブルに入っているデータを 取り出す。
⚪︎SELECT * FROM users LIMIT 50;で最初の50行のデータだけを 取り出すこともできる。
ここまででテストデータがMySQLに追加できたので、ここからはリードレプリカを作成していきます!
RDSからリードレプリカを作成
今回はRDSの作成時と同様にパブリックアクセスだけ「許可」に変更し、 他はデフォルトの設定のまま作成しました。また、config/database.ymlに リードレプリカの設定情報も追加しておいてください。
テストツール(JMeter)のセットアップ
今回はテストツールにJMeterを使用してみました!
JMeterのインストール
・まずJMeterのインストールを行う前にJavaをインストールしておく
⚪︎インストール後、ターミナルでjava -version を実行し、確認
・以下でJMeterをインストールする
⚪︎[https://jmeter.apache.org/download_jmeter.cgi:title]
・コマンドでjmeterと入力するとJMeterをGUIで起動できる
JMeterテストプランの設定
スレッドグループを作成
・TestPlanからAdd>Thread>Thread Groupにて作成する
・スレッドグループの項目を設定
⚪︎Number of Threads(同時に実行する仮想ユーザーの数)
⚪︎Ramp-Up Period (全ユーザー起動までの時間)
⚪︎Loop Count (テストシナリオの繰り返し回数)
↓詳しくはこちら参考
1. スレッド数(Number of Threads):
⚪︎この設定は、同時に実行する仮想ユーザーの数を指定します。例えば、10を設定すると、JMeterは10の仮想ユーザーを同時に起動してテストを実行します。
2. Ramp-Up Period:
⚪︎この設定は、全ての仮想ユーザーが起動するまでの時間(秒)を指定します。例えば、スレッド数を10、Ramp-Upを5秒に設定すると、1秒あたり2人の仮想ユーザーが起動します。これは、突然の大量のアクセスをシミュレートするのではなく、徐々にアクセスが増加するシナリオをシミュレートするためのものです。
3. ループ回数(Loop Count):
⚪︎この設定は、テストシナリオを何回繰り返すかを指定します。1を設定すると、各仮想ユーザーはテストシナリオを1回だけ実行します。Foreverにチェックを入れると、仮想ユーザーは無限にテストシナリオを繰り返します(手動で停止するまで)。
ちなみに今回はこちらで設定しました。
JDBC接続設定追加の設定
・Thread Groupから Add>Config Element>JDBC Connection Configurationを選択する
・以下の情報を入力します。
・変数名: 任意の名前(例: my_database)
・データベースURL: RDSのエンドポイントを入力 (RDSのエンドポイント:ポート番号/DBの名前)
・JDBCドライバクラス: MySQLの場合はcom.mysql.cj.jdbc.Driverを選択
・ユーザー名: RDSのマスターユーザー名
・パスワード: RDSのマスターパスワード
JDBCリクエストの設定
・Thread Groupから Add>Sampler>JDBC Requestを選択する
・以下の情報を入力します。
⚪︎変数名: 先ほどJDBC接続設定で設定した変数名
⚪︎Query Type: Select Statement
⚪︎SQLクエリ: 実行したいSQLクエリを記述
今回は SELECT * FROM users LIMIT 10;を設定
リスナーの指定
・JMeterのリスナーとは、テスト実行中や実行後の結果を表示・分析するもの
・Thread Groupから Add>Listenerからリスナーを選択するだけで設定は不要
⚪︎View Results Tree(個別のリクエストとその応答を詳細に確認できる)
⚪︎Aggregate Report(リクエストごとの集計情報を表示する)
ここまででJMeterの設定は終了です!
またRDSのみの検証は上記の設定で行えますが、RDS+リードレプリカの検証を行うにはプラスして以下の設定が必要です。
・RDSのみのテストプランを保存しておく(メニューから、File>Save)
・新しいテストプランを作成する
・スレッドグループを作成する
⚪︎JDBC接続設定をRDS、リードレプリカの2つ作成する
⚪︎JDBCリクエストの設定もRDS、リードレプリカの2つ作成する
Jmeterにてテスト実行
それでは、実際にテストを実行してみます!
以下のテスト実行ボタンを押すと実行できます。
テスト結果の比較
それではリスナーを使用してテスト結果を見てみます!
RDSのみ
RDS+リードレプリカ
テストで確認した項目はこちらです。
・平均レスポンスタイム (Average): リクエストの平均応答時間。
値が小さい方がパフォーマンスが良い
・スループット (Throughput): 秒あたりのリクエスト数。
値が大きい方が処理能力が高い
・最大レスポンスタイム (Max): 応答時間の最大値。
値が小さい方がピーク時の性能が良い
テスト結果は、、
・リードレプリカを導入すると、
スループットは向上したが、レスポンスタイムはRDS単体で使用するより長くなった
以下はテスト結果の詳細です。
Average (平均応答時間)
*RDSのみの場合: 509ミリ秒
*RDS+リードレプリカの場合: 608ミリ秒
平均応答時間がRDS+リードレプリカの場合でわずかに増加しています。
Throughput (スループット)
・RDSのみの場合: 10.8リクエスト/秒
・RDS+リードレプリカの場合: 18.2リクエスト/秒
スループットはRDS+リードレプリカの場合で明らかに向上しています。
Max (最大応答時間)
・RDSのみの場合: 1090ミリ秒
・RDS+リードレプリカの場合: 3825ミリ秒
最大応答時間はRDS+リードレプリカの場合で大幅に増加しています。
こちらは意外な結果となりました。
応答時間が増加している具体的な原因は断定できませんがこちらが考えられます。
・レプリカの同期の遅延: メインのRDSとリードレプリカとの間でのデータの同期に遅延が生じることがあり、時間がかかってしまった。
・不均一な負荷分散: レプリカを導入しても、すべてのリクエストが均等に分散されない場合がある。一部のレプリカに集中的にリクエストが来ることで、そのレプリカの応答時間が長くなる可能性も考えられる。 最後まで読んでいただきありがとうございました!今回の検証では、RDSのみを使用した場合と、RDSとリードレプリカを併用した場合の性能を比較しました。結果として、リードレプリカの使用は読み取り負荷が高い場面での負荷分散に有効であることが確認できました。ちなみにAWSの学習中ですが、実際に構築すると仕組みがだいぶ理解できたような気がします。
終わりに
最後まで読んでいただきありがとうございました!
今回の検証では、RDSのみを使用した場合と、RDSとリードレプリカを併用した場合の性能を比較しました。結果として、リードレプリカの使用は読み取り負荷が高い場面での負荷分散に有効であることが確認できました。ちなみにAWSの学習中ですが、実際に構築すると仕組みがだいぶ理解できたような気がします。
divxでは一緒に働ける仲間を募集しています。
興味があるかたはぜひ採用ページを御覧ください。