この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
よく訓練されたアップル信者、都元です。今回はMySQLのクライアント負荷エミュレーションツールmysqlslapを使って、Amazon RDSの性能を測定してみました。
このエントリーの初期版では、クライアントのEC2インスタンスサイズをsmallにしていましたが、クライアント側がボトルネックにならないよう、m3.2xlargeで再測定しています。また、測定回数(iterations)も、初期版では1でしたが、現在は10回の平均を取った数値で再測定しています。
Amazon RDSではdb.t1.microからdb.m2.4xlargeまで様々なインスタンスクラスが選択できます *1。それぞれCPUやメモリの他、I/O性能も「低速」「標準」「高速」といった差別化がはかられています。
とは言え、それぞれのインスタンスクラスにおいて、総合的なパフォーマンスはどの程度なのか、気になりますよね! ということでmysqlslapというMySQL標準のユーティリティを使って測ってみました。
性能試験用RDSとテスト用サーバの起動
まず、測定用のRDSを用意します。コピペで再現性のあるインスタンス起動ができるよう、コマンドラインにて。インスタンスの種類はdb.t1.micro、db.m1.small、飛んでdb.m2.4xlarge、さらにはdb.m2.4xlarge 10000IOPSの4つを測定対象としました。インスタンスクラス以外の差が出ないよう、その他のパラメータはほぼ一緒 *2です。
$ aws --region ap-northeast-1 rds create-db-instance \
--master-username classmethod \
--master-user-password cmsamplepass \
--engine MySQL \
--allocated-storage 5 \
--engine-version 5.5.27 \
--availability-zone ap-northeast-1c \
--publicly-accessible \
--db-instance-class db.t1.micro \
--db-instance-identifier cm-test-micro
$ aws --region ap-northeast-1 rds create-db-instance \
--master-username classmethod \
--master-user-password cmsamplepass \
--engine MySQL \
--allocated-storage 5 \
--engine-version 5.5.27 \
--availability-zone ap-northeast-1c \
--publicly-accessible \
--db-instance-class db.m1.small \
--db-instance-identifier cm-test-small
$ aws --region ap-northeast-1 rds create-db-instance \
--master-username classmethod \
--master-user-password cmsamplepass \
--engine MySQL \
--allocated-storage 5 \
--engine-version 5.5.27 \
--availability-zone ap-northeast-1c \
--publicly-accessible \
--db-instance-class db.m2.4xlarge \
--db-instance-identifier cm-test-4xlarge
$ aws --profile cm-team-cloud --region ap-northeast-1 rds create-db-instance \
--master-username classmethod \
--master-user-password cmsamplepass \
--engine MySQL \
--allocated-storage 1000 \
--iops 10000 \
--engine-version 5.5.27 \
--availability-zone ap-northeast-1c \
--publicly-accessible \
--db-instance-class db.m2.4xlarge \
--db-instance-identifier cm-test-4xlarge-iops10000
しばらく待つとステータスがavailableとなりますので、ホスト名を確認しましょう。
これらのDBに対して、クライアント端末からテストをしても良いのですが、通信回線のオーバーヘッドが影響してしまうので、RDSとは別にEC2インスタンスを同じAZ(ap-northeast-1c)に立てて、そこからテストすることにします。EC2側のボトルネックを最小限にするため、m3.2xlarge(m3の最大級クラス)を贅沢に使ってみました。
先ほど作成したDBインスタンスはdefaultのセキュリティグループに属しているため、このテスト用EC2インスタンスからこれらのRDSのMySQLにアクセスできるように設定の調整を行ってください。
mysqlslapの実行
テスト用のEC2にログインし、まずはMySQLのクライアントをインストールします。これでmysqlslapが使えるようになります。
$ sudo yum -y install mysql
(おおぅ、いつもt1.microでyumを使って何かをインストールする時と、スピード感が違います。恐るべしm3.2xlarge。)
mysqlslapについてはココ(v5.1の日本語版ドキュメント)とかココ(v5.5の英語版ドキュメント)を参照してください。要するに、指定したMySQLに様々なクエリを大量に投げて、その実行に掛かった時間を測定するツールです。
コマンドはこんな感じ。
$ mysqlslap \
--user=classmethod \
--password=cmsamplepass \
--host=cm-test-micro.foobarbazqux.ap-northeast-1.rds.amazonaws.com \
--port=3306 \
--engine=innodb \
--auto-generate-sql \
--auto-generate-sql-load-type=read \
--auto-generate-sql-add-autoincrement \
--number-char-cols=3 \
--number-int-cols=5 \
--number-of-queries=10000 \
--concurrency=3 \
--iterations=10
このコマンドでは、指定したMySQLインスタンスに対して、innodbでテーブルを作成します。autoincrementのカラムを1つ作り、VARCHAR型のカラムを3つ、INT型のカラムを5つ作ります。この辺りはなんとなく適当に決めました。このテーブルに対して1万回のクエリを3つのスレッドから投げます。つまり、1スレッドにつき約3333回のクエリを投げる感じです。
これを--iterations=10という指定により、10回同じテストを繰り返し、平均値をとります。
また、--auto-generate-sql-load-type=readというオプションはテーブルに対してread (scan)を行う性能試験です。その他、write (insert)、key (PKによる読み込み)、update (PKによるupdate)、mixed (scanとinsertのハイブリッド)が選択できます。
microインスタンスに対してsqlslapコマンドを実行した結果は以下の通り。平均、最小値、最大値が表示されています。
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 48.535 seconds
Minimum number of seconds to run all queries: 38.508 seconds
Maximum number of seconds to run all queries: 49.810 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
同様に、small, 4xlarge, 4xlarge-iops10000 の結果は以下の通り。
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 11.449 seconds
Minimum number of seconds to run all queries: 9.747 seconds
Maximum number of seconds to run all queries: 12.284 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 3.451 seconds
Minimum number of seconds to run all queries: 3.128 seconds
Maximum number of seconds to run all queries: 3.572 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 3.461 seconds
Minimum number of seconds to run all queries: 3.195 seconds
Maximum number of seconds to run all queries: 3.517 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
この条件下では、smallはmicroの約4倍のread性能を持つ、ということですね。この調子で、各インスタンスについて、read, write, key, update, mixed の各性能を測定しました。ちなみに、keyに関しては一瞬でベンチマークが終わってしまったので、--number-of-queries=100000で測定しました。
時間単価の安いインスタンスを使っているわけでもないので、測定は以下のようなスクリプトを使ってさっくりと終わらせました。
#! /bin/bash
instancenames=(cm-test-micro cm-test-small cm-test-4xlarge cm-test-4xlarge-iops10000)
loadtypes=(read write key update mixed)
for loadtype in ${loadtypes[@]}; do
if [ "$loadtype" = "key" ]; then
numberofqueries=100000
else
numberofqueries=10000
fi
for instancename in ${instancenames[@]}; do
echo "======== ${loadtype} on ${instancename} (${numberofqueries} times) ========"
mysqlslap \
--user=classmethod \
--password=cmsamplepass \
--host=${instancename}.foobarbazqux.ap-northeast-1.rds.amazonaws.com \
--port=3306 \
--engine=innodb \
--auto-generate-sql \
--auto-generate-sql-load-type=${loadtype} \
--auto-generate-sql-add-autoincrement \
--number-char-cols=3 \
--number-int-cols=5 \
--number-of-queries=${numberofqueries} \
--concurrency=3 \
--iterations=10
done
done
片付け
さて、結果はさておき、使ったRDSインスタンスは削除しておきましょう。テストクライアントとして使ったEC2もね。
$ aws --region ap-northeast-1 rds delete-db-instance --db-instance-identifier cm-test-micro --skip-final-snapshot
$ aws --region ap-northeast-1 rds delete-db-instance --db-instance-identifier cm-test-small --skip-final-snapshot
$ aws --region ap-northeast-1 rds delete-db-instance --db-instance-identifier cm-test-4xlarge --skip-final-snapshot
$ aws --region ap-northeast-1 rds delete-db-instance --db-instance-identifier cm-test-4xlarge-iops10000 --skip-final-snapshot
結果まとめ
まぁ、テーブルの構成を決めるパラメータも適当ですし、実運用下ではJOIN等複雑な処理が行われるので、一概に言うことはできないかもしれません。が、とりあえずこんな感じの成績になりました。
クラス | READ | WRITE | KEY | UPDATE | MIXED |
---|---|---|---|---|---|
db.t1.micro | 48.535 | 38.623 | 16.045 | 36.795 | 11.057 |
db.t1.small | 11.449 | 9.070 | 32.336 | 9.359 | 5.342 |
db.m2.4xlarge | 3.451 | 6.689 | 11.698 | 6.679 | 4.036 |
db.m2.4xlarge (10,000 IOPS) | 3.461 | 5.101 | 11.862 | 5.030 | 3.484 |
数カ所で下克上が発生してますが、バースト等、AWSクラウド特有のの問題が影響しているのかな、と思っています。それを含めても、概ね順調にパフォーマンスがアップしていますね。
生データ
一応、最後に生データ貼っておきますね :-)
======== read on cm-test-micro (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 48.535 seconds
Minimum number of seconds to run all queries: 38.508 seconds
Maximum number of seconds to run all queries: 49.810 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== read on cm-test-small (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 11.449 seconds
Minimum number of seconds to run all queries: 9.747 seconds
Maximum number of seconds to run all queries: 12.284 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== read on cm-test-4xlarge (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 3.451 seconds
Minimum number of seconds to run all queries: 3.128 seconds
Maximum number of seconds to run all queries: 3.572 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== read on cm-test-4xlarge-iops10000 (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 3.461 seconds
Minimum number of seconds to run all queries: 3.195 seconds
Maximum number of seconds to run all queries: 3.517 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== write on cm-test-micro (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 38.623 seconds
Minimum number of seconds to run all queries: 35.719 seconds
Maximum number of seconds to run all queries: 44.729 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== write on cm-test-small (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 9.070 seconds
Minimum number of seconds to run all queries: 8.564 seconds
Maximum number of seconds to run all queries: 9.716 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== write on cm-test-4xlarge (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 6.689 seconds
Minimum number of seconds to run all queries: 6.453 seconds
Maximum number of seconds to run all queries: 7.002 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== write on cm-test-4xlarge-iops10000 (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 5.101 seconds
Minimum number of seconds to run all queries: 5.039 seconds
Maximum number of seconds to run all queries: 5.166 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== key on cm-test-micro (100000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 16.045 seconds
Minimum number of seconds to run all queries: 15.773 seconds
Maximum number of seconds to run all queries: 16.447 seconds
Number of clients running queries: 3
Average number of queries per client: 33333
======== key on cm-test-small (100000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 32.336 seconds
Minimum number of seconds to run all queries: 30.788 seconds
Maximum number of seconds to run all queries: 39.243 seconds
Number of clients running queries: 3
Average number of queries per client: 33333
======== key on cm-test-4xlarge (100000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 11.698 seconds
Minimum number of seconds to run all queries: 11.311 seconds
Maximum number of seconds to run all queries: 11.979 seconds
Number of clients running queries: 3
Average number of queries per client: 33333
======== key on cm-test-4xlarge-iops10000 (100000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 11.862 seconds
Minimum number of seconds to run all queries: 11.519 seconds
Maximum number of seconds to run all queries: 12.115 seconds
Number of clients running queries: 3
Average number of queries per client: 33333
======== update on cm-test-micro (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 36.795 seconds
Minimum number of seconds to run all queries: 34.182 seconds
Maximum number of seconds to run all queries: 39.357 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== update on cm-test-small (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 9.359 seconds
Minimum number of seconds to run all queries: 8.617 seconds
Maximum number of seconds to run all queries: 10.843 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== update on cm-test-4xlarge (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 6.679 seconds
Minimum number of seconds to run all queries: 6.418 seconds
Maximum number of seconds to run all queries: 6.884 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== update on cm-test-4xlarge-iops10000 (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 5.030 seconds
Minimum number of seconds to run all queries: 4.955 seconds
Maximum number of seconds to run all queries: 5.112 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== mixed on cm-test-micro (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 11.057 seconds
Minimum number of seconds to run all queries: 10.620 seconds
Maximum number of seconds to run all queries: 12.743 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== mixed on cm-test-small (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 5.342 seconds
Minimum number of seconds to run all queries: 5.160 seconds
Maximum number of seconds to run all queries: 5.529 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== mixed on cm-test-4xlarge (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 4.036 seconds
Minimum number of seconds to run all queries: 3.774 seconds
Maximum number of seconds to run all queries: 4.284 seconds
Number of clients running queries: 3
Average number of queries per client: 3333
======== mixed on cm-test-4xlarge-iops10000 (10000 times) ========
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 3.484 seconds
Minimum number of seconds to run all queries: 3.336 seconds
Maximum number of seconds to run all queries: 3.696 seconds
Number of clients running queries: 3
Average number of queries per client: 3333