mysqlslapを使ってRDSのMySQLについて各クラスのパフォーマンス測定
よく訓練されたアップル信者、都元です。今回は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