ちょっと話題の記事

mysqlslapを使ってRDSのMySQLについて各クラスのパフォーマンス測定

この記事は公開されてから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.microdb.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クラウド特有のの問題が影響しているのかな、と思っています。それを含めても、概ね順調にパフォーマンスがアップしていますね。

Amazonでチェックする

生データ

一応、最後に生データ貼っておきますね :-)

======== 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

脚注

  1. 執筆時点、東京リージョン(ap-northeast-1)にて。
  2. IOPS指定インスタンスは、--allocated-storage 1000とする必要があるので、そうしてあります。