2013年4月1日月曜日

Spiderってなんじゃ?(tpcc-mysqlでベンチマークをとってみた)

久しぶりのSpiderの話題です。
今回はtpcc-mysqlというベンチマークツールを使ってSpiderのベンチマークをとってみました。

mysqlにかぎらずDBのベンチマークツールの多くは、TPCという団体の定めたベンチマーク仕様に基いて実装されていて、トランザクションやアクセスなどのDB用途によっていくつかのベンチマークタイプに分かれていて、OLTP向けのTPC-Eや意思決定システム向けのTPC-HやTPC-DSなど色々あるようです。
http://www.tpc.org/information/benchmarks.asp

その中で、TPC-Cというのが複数ユーザーのトランザクションが発生するベンチマーク仕様で、顧客が商品を注文し在庫チェックと発送などをシュミレートするもののようです。
そして、このTPC-C仕様をmysqlのベンチマークとして実装したものが、tpcc-mysqlです。

このあたりのことは、以下のサイトに詳しく書かれていて非常に勉強になりました。
データベース負荷テストツールまとめ(2)
tpcc-mysqlによるMySQLのベンチマーク

今回はtpcc-mysqlを使ってSpider+RDS*4とRDS単体をテストしてみます。
構成は以下の通りです。




tpcc-mysqlのインストール


まず、ベンチ用のインスタンス(10.0.1.99)にtpcc-mysqlをインストールします。
# yum install bzr mysql-devel -y
$ mkdir ~/test
$ cd ~/test/
$ bzr init
$ bzr branch lp:~percona-dev/perconatools/tpcc-mysql
$ cd tpcc-mysql/
$ cd src
$ make all

これでインストールできました。
~/test/tpcc-mysql配下にtpcc_loadとtpcc_startという実行ファイルができていれば成功です。
$ ls -l ~/test/tpcc-mysql/
合計 248
-rw-rw-r-- 1 appadmin appadmin    851  4月  1 20:03 2013 README
-rw-rw-r-- 1 appadmin appadmin   1621  4月  1 20:03 2013 add_fkey_idx.sql
-rw-rw-r-- 1 appadmin appadmin    317  4月  1 20:03 2013 count.sql
-rw-rw-r-- 1 appadmin appadmin   3105  4月  1 20:03 2013 create_table.sql
-rw-rw-r-- 1 appadmin appadmin    763  4月  1 20:03 2013 drop_cons.sql
-rw-rw-r-- 1 appadmin appadmin    477  4月  1 20:03 2013 load.sh
drwxrwxr-x 2 appadmin appadmin   4096  4月  1 20:03 2013 schema2
drwxrwxr-x 5 appadmin appadmin   4096  4月  1 20:03 2013 scripts
drwxrwxr-x 2 appadmin appadmin   4096  4月  1 20:33 2013 src
-rwxrwxr-x 1 appadmin appadmin  60751  4月  1 20:33 2013 tpcc_load
-rwxrwxr-x 1 appadmin appadmin 154558  4月  1 20:33 2013 tpcc_start



テーブルの準備


予めstressという名前のデータベースを作成しておきます。
(名前はなんでも構いません)

次に、対象のテーブルとインデックスを作成します。
tpcc-mysql配下には、テーブルとインデックスの作成用DDL(create_table.sql、add_fkey_idx.sql)が付属しています。

インデックス用のSQLファイルには外部キーの作成も含まれていますが、
Spiderでは外部キーが使用できないため、外部キーからインデックス部分を除いたものを作ります。


また、Spiderノード用のテーブル作成DDLも作成します。

またSpiderノードからRDSに接続するときのために、Spiderノードのmy.cnfに以下の設定をしておきます。
spider_remote_sql_log_off = 1


次に作成したDDLを各インスタンスに流し込みます。
$ mysql -h 10.0.1.172 -u memorycraft stress -p < ~/test/tpcc-mysql/create_table.sql
$ mysql -h 10.0.1.20 -u memorycraft stress -p < ~/test/tpcc-mysql/create_table-spider.sql
$ mysql -h data1.cwnvl1ncuiwq.ap-northeast-1.rds.amazonaws.com -u memorycraft stress -p < ~/test/tpcc-mysql/create_table.sql
$ mysql -h data2.cwnvl1ncuiwq.ap-northeast-1.rds.amazonaws.com -u memorycraft stress -p < ~/test/tpcc-mysql/create_table.sql
$ mysql -h data3.cwnvl1ncuiwq.ap-northeast-1.rds.amazonaws.com -u memorycraft stress -p < ~/test/tpcc-mysql/create_table.sql
$ mysql -h data4.cwnvl1ncuiwq.ap-northeast-1.rds.amazonaws.com -u memorycraft stress -p < ~/test/tpcc-mysql/create_table.sql

$ mysql -h 10.0.1.172 -u memorycraft stress -p < ~/test/tpcc-mysql/add_fkey_idx.sql
$ mysql -h 10.0.1.20 -u memorycraft stress -p < ~/test/tpcc-mysql/add_fkey_idx.sql
$ mysql -h data1.cwnvl1ncuiwq.ap-northeast-1.rds.amazonaws.com -u memorycraft stress -p < ~/test/tpcc-mysql/add_fkey_idx.sql
$ mysql -h data2.cwnvl1ncuiwq.ap-northeast-1.rds.amazonaws.com -u memorycraft stress -p < ~/test/tpcc-mysql/add_fkey_idx.sql
$ mysql -h data3.cwnvl1ncuiwq.ap-northeast-1.rds.amazonaws.com -u memorycraft stress -p < ~/test/tpcc-mysql/add_fkey_idx.sql
$ mysql -h data4.cwnvl1ncuiwq.ap-northeast-1.rds.amazonaws.com -u memorycraft stress -p < ~/test/tpcc-mysql/add_fkey_idx.sql


ここまででDDLは出来上がりました。


テストデータの投入


次にデータの投入です。データの投入には先ほどのビルドで出来たtpcc_loadコマンドを使用します。
第1〜第4引数まではそれぞれホスト、DB名、DBユーザー、DBパスワードを指定し、第5引数には倉庫(warehouse)の数を指定します。 warehouseは1つにつき一番レコードの多いorder_lineテーブルで30万件程度に増えます。ここではwarehouseを100(order_lineテーブルで3000万件程度) に設定します。
このデータ投入処理はとても時間がかかります。
./tpcc_load 10.0.1.172 stress memorycraft xxxxxxxxx 100
./tpcc_load 10.0.1.20 stress memorycraft xxxxxxxxx 100



テストの実行


データがロードできたらtpcc_startでテストを実行します。
-w以降のオプションは以下の通りです。

  • -w:warehouseの数、基本的にはloadで設定したのと同じ値
  • -c:接続数 
  • -r:待機時間 
  • -l:実行時間(秒) 

基本的にはwarehouse数と、接続数を調整していろいろなパターンでテストしていきます。
./tpcc_start -h 10.0.1.172 -P 3306 -d stress -u memorycraft -p xxxxxxxxx -w 100 -c 10 -r 300 -l 3600
./tpcc_start -h 10.0.1.20 -P 3306 -d stress -u memorycraft -p xxxxxxxxx -w 100 -c 10 -r 300 -l 3600


結果は以下のようになり、一番最後のTpmC(1分間に処理できたトランザクション数)が指標になります。
***************************************
*** ###easy### TPC-C Load Generator ***
***************************************
option h with value '10.0.1.20'
option P with value '3306'
option d with value 'stress'
option u with value 'memorycraft'
option p with value 'satoru00'
option w with value '100'
option c with value '10'
option r with value '300'
option l with value '3600'

     [server]: 10.0.1.20
     [port]: 3306
     [DBname]: stress
       [user]: memorycraft
       [pass]: satoru00
  [warehouse]: 100
 [connection]: 10
     [rampup]: 300 (sec.)
    [measure]: 3600 (sec.)

RAMP-UP TIME.(300 sec.)

MEASURING START.

  10, 257(0):3.061|3.773, 258(0):0.580|0.773, 25(0):0.297|0.415, 26(0):3.753|4.259, 26(0):9.967|11.042
  20, 265(0):3.003|3.222, 264(0):0.570|0.617, 27(0):0.252|0.329, 26(0):3.448|3.478, 26(0):8.935|9.011
  30, 258(0):3.185|3.452, 256(0):0.626|0.684, 26(0):0.374|0.414, 25(0):3.700|4.063, 26(0):9.790|10.474
  40, 247(0):3.191|3.331, 249(0):0.605|0.630, 24(0):0.279|0.298, 26(0):3.702|4.258, 24(0):10.012|10.016
  50, 251(0):2.930|2.980, 248(0):0.526|0.548, 25(0):0.258|0.275, 24(0):3.111|3.113, 25(0):8.949|8.967
  60, 252(0):2.864|3.176, 254(0):0.544|0.585, 25(0):0.248|0.253, 26(0):3.249|3.315, 26(0):9.449|9.567
  70, 249(0):2.850|2.878, 247(0):0.527|0.540, 25(0):0.247|0.276, 25(0):3.126|3.156, 24(0):9.074|9.135
  80, 246(0):3.337|3.388, 249(0):0.651|0.663, 25(0):0.310|0.338, 24(0):3.897|3.967, 25(0):11.210|11.281
  90, 261(0):2.923|3.133, 262(0):0.548|0.577, 26(0):0.284|0.297, 27(0):3.218|3.283, 27(0):9.433|9.563
 100, 262(0):2.910|3.139, 258(0):0.528|0.561, 27(0):0.254|0.282, 26(0):3.170|3.193, 26(0):8.908|9.046
 110, 254(0):3.013|3.200, 253(0):0.570|0.586, 25(0):0.279|0.289, 25(0):3.328|3.511, 25(0):9.278|9.294
 120, 269(0):2.912|2.975, 272(0):0.546|0.553, 26(0):0.250|0.259, 27(0):3.180|3.212, 26(0):8.939|8.954
 130, 266(0):2.936|2.960, 265(0):0.533|0.567, 27(0):0.257|0.264, 26(0):3.190|3.192, 27(0):9.350|9.428
 140, 263(0):2.936|2.963, 263(0):0.578|0.632, 26(0):0.256|0.259, 27(0):3.348|3.456, 27(0):9.167|9.708
 150, 248(0):2.888|2.948, 247(0):0.545|0.603, 25(0):0.252|0.258, 24(0):3.144|3.165, 24(0):9.086|9.450
 160, 231(0):2.936|3.002, 232(0):0.526|0.539, 23(0):0.245|0.262, 24(0):3.199|3.237, 24(0):8.894|10.282
~(略)~
3480, 265(0):2.957|3.211, 265(0):0.534|0.603, 26(0):0.264|0.267, 26(0):3.267|3.330, 26(0):9.178|9.661
3490, 262(0):2.919|2.949, 266(0):0.527|0.538, 26(0):0.249|0.251, 27(0):3.178|3.183, 27(0):8.766|9.398
3500, 259(0):2.952|3.189, 257(0):0.541|0.652, 27(0):0.263|0.282, 26(0):3.266|3.279, 25(0):9.387|9.501
3510, 259(0):2.901|3.069, 262(0):0.532|0.612, 25(0):0.246|0.252, 25(0):3.205|3.226, 27(0):8.785|9.184
3520, 260(0):2.880|2.899, 259(0):0.519|0.586, 26(0):0.253|0.254, 27(0):3.168|3.189, 25(0):8.908|9.342
3530, 259(0):2.914|3.136, 250(0):0.534|0.604, 25(0):0.269|0.278, 25(0):3.296|3.330, 26(0):8.985|9.735
3540, 253(0):3.034|3.061, 261(0):0.572|0.632, 27(0):0.258|0.262, 26(0):3.234|3.319, 26(0):9.063|9.236
3550, 270(0):2.959|3.097, 269(0):0.522|0.547, 26(0):0.254|0.273, 27(0):3.242|3.244, 27(0):8.790|9.263
3560, 251(0):3.057|3.258, 250(0):0.609|0.653, 26(0):0.276|0.360, 25(0):3.360|3.444, 25(0):9.423|9.474
3570, 244(0):3.031|3.133, 248(0):0.546|0.618, 24(0):0.251|0.259, 24(0):3.286|3.299, 25(0):8.948|9.190
3580, 260(0):2.933|3.057, 260(0):0.527|0.542, 26(0):0.243|0.249, 27(0):3.175|3.190, 26(0):8.928|9.061
3590, 260(0):3.000|3.370, 255(0):0.560|0.667, 26(0):0.257|0.310, 25(0):3.327|3.329, 25(0):9.263|9.397
3600, 262(0):2.933|3.016, 263(0):0.523|0.540, 27(0):0.256|0.257, 27(0):3.180|3.230, 26(0):9.017|9.607

STOPPING THREADS..........


  [0] sc:91448  lt:0  rt:0  fl:0 
  [1] sc:91446  lt:0  rt:0  fl:0 
  [2] sc:9145  lt:0  rt:0  fl:0 
  [3] sc:9145  lt:0  rt:0  fl:0 
  [4] sc:9144  lt:0  rt:0  fl:0 
 in 3600 sec.


  [0] sc:91448  lt:0  rt:0  fl:0 
  [1] sc:91446  lt:0  rt:0  fl:0 
  [2] sc:9145  lt:0  rt:0  fl:0 
  [3] sc:9145  lt:0  rt:0  fl:0 
  [4] sc:9144  lt:0  rt:0  fl:0 

 (all must be [OK])
 [transaction percentage]
        Payment: 43.48% (>=43.0%) [OK]
   Order-Status: 4.35% (>= 4.0%) [OK]
       Delivery: 4.35% (>= 4.0%) [OK]
    Stock-Level: 4.35% (>= 4.0%) [OK]
 [response time (at least 90% passed)]
      New-Order: 100.00%  [OK]
        Payment: 100.00%  [OK]
   Order-Status: 100.00%  [OK]
       Delivery: 100.00%  [OK]
    Stock-Level: 100.00%  [OK]


                 1524.133 TpmC


何通りかテストをした結果、RDS単体とSpider+RDS*4で結果が入れ替わる条件がありました。

タイプデータ数接続数RDS*1Spider+RDS*4
mediumwarehouse=100102287.250 tpm1524.133 tpm
mediumwarehouse=100202368.133 tpm1564.283 tpm
mediumwarehouse=150201418.667 tpm1540.333 tpm


作者の斯波さんにも伺ったのですが、Spiderの特性としてデータノードへのオーバーヘッドがある分、通常の単体DBに比べると最初はパフォーマンスが落ちますが、並列アクセス(同時アクセス数)が多くなり、データ数も多くなってくるとSpiderの優位性が出てくるとのことで、それが上の結果と一致しました。

細かなチューニングなどで結果も変わってくるかと思いますが、最初からSpider構成にするというよりも、負荷やデータ量の拡大に応じて移行していくのがよいのかなと感じました。
前述のように外部キーが使用できないなど、Spiderはいくつかの特殊な制限があるため、運用後のSpiderによるスケールアウトを視野に入れているのであれば、Spiderの制限などを見越したテーブル、データ設計なども考慮したほうが良いのかもしれません。

以上です。