この章では、MySQLを使用して簡単な負荷テストを行うまでの手順を説明します。
MySQLのtestデータベースにtutorialテーブルを作成し、テストデータをINSERTします。
> mysql test
mysql> CREATE TABLE tutorial (id INT PRIMARY KEY, data VARCHAR(10)) ENGINE = InnoDB;
mysql> INSERT INTO tutorial (id, data) VALUES (1, 'aaaaaaaaaa');
mysql> INSERT INTO tutorial (id, data) VALUES (2, 'bbbbbbbbbb');
mysql> INSERT INTO tutorial (id, data) VALUES (3, 'cccccccccc');
mysql> INSERT INTO tutorial (id, data) VALUES (4, 'dddddddddd');
mysql> INSERT INTO tutorial (id, data) VALUES (5, 'eeeeeeeeee');
テーブルの中身は以下のようになります。
mysql> SELECT * FROM tutorial ORDER BY id;
+----+------------+
| id | data |
+----+------------+
| 1 | aaaaaaaaaa |
| 2 | bbbbbbbbbb |
| 3 | cccccccccc |
| 4 | dddddddddd |
| 5 | eeeeeeeeee |
+----+------------+
5 rows in set (0.00 sec)
jdbcrunner-1.1.jarを任意のディレクトリに配置し、環境変数CLASSPATHを設定します。Windowsの場合はsetコマンドで環境変数を設定することができます。
> dir
C:\jdbcrunner のディレクトリ
2010/04/04 23:59 <DIR> .
2010/04/04 23:59 <DIR> ..
2010/04/04 23:53 2,839,507 jdbcrunner-1.1.jar
> set CLASSPATH=jdbcrunner-1.1.jar
Linuxなどでbashを使用している場合は、exportコマンドで設定します。
$ export CLASSPATH=jdbcrunner-1.1.jar
ツールの起動クラスはパッケージなしのJRです。追加のオプションなしで実行すると、簡単な使い方が表示されます。
> java JR
JdbcRunner 1.1
スクリプトファイルが指定されていません
usage: java JR <script> [options]
-autoCommit <arg> オートコミットモードを有効化または無効化します (デフォルト : true (有効))
-connPoolSize <arg> コネクションプールの物理接続数を指定します (デフォルト : nAgents)
-debug デバッグモードを有効にします (デフォルト : false)
-jdbcDriver <arg> JDBCドライバのクラス名を指定します (デフォルト : (なし))
-jdbcPass <arg> データベースユーザのパスワードを指定します (デフォルト : (なし))
-jdbcUrl <arg> JDBC接続URLを指定します (デフォルト : jdbc:mysql://localhost:3306/test)
-jdbcUser <arg> データベースのユーザ名を指定します (デフォルト : (なし))
-logDir <arg> ログの出力先ディレクトリを指定します (デフォルト : .)
-measurementTime <arg>測定時間[sec]を指定します (デフォルト : 60)
-nAgents <arg> エージェント数を指定します (デフォルト : 1)
-param0 <arg> 変数param0に値を設定します
-param1 <arg> 変数param1に値を設定します
-param2 <arg> 変数param2に値を設定します
-param3 <arg> 変数param3に値を設定します
-param4 <arg> 変数param4に値を設定します
-param5 <arg> 変数param5に値を設定します
-param6 <arg> 変数param6に値を設定します
-param7 <arg> 変数param7に値を設定します
-param8 <arg> 変数param8に値を設定します
-param9 <arg> 変数param9に値を設定します
-scriptCharset <arg> スクリプトの文字セットを指定します
-sleepTime <arg> トランザクションごとのスリープ時間[msec]を指定します (デフォルト : 0)
-stmtCacheSize <arg> コネクションあたりの文キャッシュ数を指定します (デフォルト : 10)
-throttle <arg> スループットの上限値[tps]を指定します (デフォルト : 0 (無制限))
-trace トレースモードを有効にします (デフォルト : false)
-warmupTime <arg> 測定前にあらかじめ負荷をかけておく時間[sec]を指定します (デフォルト : 10)
JdbcRunnerでは、負荷テストのシナリオをスクリプトで定義します。以下のスクリプトをtest.jsというファイル名で作成します。
function run() {
var param = random(1, 5);
query("SELECT data FROM tutorial WHERE id = $int", param);
}
このスクリプトは「1以上5以下の乱数を生成し、生成された値をint型としてクエリのパラメータにバインドして実行する」というファンクションを定義するものです。JdbcRunnerはrun()ファンクションで定義された処理を指定された多重度で指定された時間だけ繰り返し実行し、スループットとレスポンスタイムを出力します。
作成したスクリプトをオプションに指定して実行すると、負荷テストが開始されます。
> java JR test.js
00:02:55 [INFO ] > JdbcRunner 1.1
00:02:55 [INFO ] [Config]
Program start time : 20100405-000254
Script filename : test.js
JDBC driver : -
JDBC URL : jdbc:mysql://localhost:3306/test
JDBC user :
Warmup time : 10 sec
Measurement time : 60 sec
Number of tx types : 1
Number of agents : 1
Connection pool size : 1
Statement cache size : 10
Auto commit : true
Sleep time : 0 msec
Throttle : - tps
Debug mode : false
Trace mode : false
Log directory : .
Parameter 0 : 0
Parameter 1 : 0
Parameter 2 : 0
Parameter 3 : 0
Parameter 4 : 0
Parameter 5 : 0
Parameter 6 : 0
Parameter 7 : 0
Parameter 8 : 0
Parameter 9 : 0
00:02:56 [INFO ] [Warmup] -9 sec, 3184 tps, (3184 tx)
00:02:57 [INFO ] [Warmup] -8 sec, 4616 tps, (7800 tx)
00:02:58 [INFO ] [Warmup] -7 sec, 4682 tps, (12482 tx)
00:02:59 [INFO ] [Warmup] -6 sec, 4524 tps, (17006 tx)
00:03:00 [INFO ] [Warmup] -5 sec, 4506 tps, (21512 tx)
00:03:01 [INFO ] [Warmup] -4 sec, 4566 tps, (26078 tx)
00:03:02 [INFO ] [Warmup] -3 sec, 4671 tps, (30749 tx)
00:03:03 [INFO ] [Warmup] -2 sec, 4554 tps, (35303 tx)
00:03:04 [INFO ] [Warmup] -1 sec, 4570 tps, (39873 tx)
00:03:05 [INFO ] [Warmup] 0 sec, 4748 tps, (44621 tx)
00:03:06 [INFO ] [Progress] 1 sec, 4757 tps, 4757 tx
00:03:07 [INFO ] [Progress] 2 sec, 4702 tps, 9459 tx
00:03:08 [INFO ] [Progress] 3 sec, 4695 tps, 14154 tx
00:03:09 [INFO ] [Progress] 4 sec, 4832 tps, 18986 tx
00:03:10 [INFO ] [Progress] 5 sec, 4674 tps, 23660 tx
...
00:04:01 [INFO ] [Progress] 56 sec, 4829 tps, 267190 tx
00:04:02 [INFO ] [Progress] 57 sec, 4708 tps, 271898 tx
00:04:03 [INFO ] [Progress] 58 sec, 4841 tps, 276739 tx
00:04:04 [INFO ] [Progress] 59 sec, 4834 tps, 281573 tx
00:04:05 [INFO ] [Progress] 60 sec, 4799 tps, 286372 tx
00:04:05 [INFO ] [Total tx count] 286373 tx
00:04:05 [INFO ] [Throughput] 4772 tps
00:04:05 [INFO ] [Response time (minimum)] 0 msec
00:04:05 [INFO ] [Response time (50%tile)] 0 msec
00:04:05 [INFO ] [Response time (90%tile)] 0 msec
00:04:05 [INFO ] [Response time (95%tile)] 0 msec
00:04:05 [INFO ] [Response time (99%tile)] 0 msec
00:04:05 [INFO ] [Response time (maximum)] 2 msec
00:04:05 [INFO ] < JdbcRunner SUCCESS
負荷テストを開始すると、標準出力に負荷テストの設定、進捗状況、測定結果が出力されます。同様の内容はログファイルjdbcrunner.logにも出力されます。負荷テストの設定のセクションからは、例えば以下のような情報が読み取れます。
進捗状況のセクションからは、毎秒およそ4,700トランザクションが実行されていることが読み取れます。ここで言うトランザクションとは、スクリプトに定義されたrun()ファンクションを1回実行することです。必ずしもRDBMSにとってのトランザクション数と一致するわけではない点に注意してください。
測定結果のセクションには、合計のトランザクション数、スループット、レスポンスタイムが出力されます。合計のトランザクション数には、ウォームアップ時間に行われたトランザクションは加算されません。レスポンスタイムはrun()ファンクションを1回実行するのにかかった時間のことで、最小値、50パーセンタイル値(中央値)、90パーセンタイル値、95パーセンタイル値、99パーセンタイル値、最大値の6種類が出力されます。また、レスポンスタイムが0ミリ秒というのは正確には0ミリ秒以上1ミリ秒未満であることを示しています。
負荷テストが正常終了すると、ログファイルjdbcrunner.logの他に2つの結果ファイルが出力されます。
> dir
C:\jdbcrunner のディレクトリ
2010/04/05 00:04 <DIR> .
2010/04/05 00:04 <DIR> ..
2010/04/04 23:53 2,839,507 jdbcrunner-1.1.jar
2010/04/05 00:04 6,112 jdbcrunner.log
2010/04/05 00:04 49 log_20100405-000254_r.csv
2010/04/05 00:04 566 log_20100405-000254_t.csv
2010/04/05 00:01 116 test.js
log_20100405-000254_r.csvと末尾に「_r」がついたCSVファイルは、レスポンスタイムの度数分布データです。レスポンスタイムごとにトランザクション実行数が出力されます。
Response time[msec],Count
0,286262
1,95
2,16
log_20100405-000254_t.csvと末尾に「_t」がついたCSVファイルは、スループットの時系列データです。
Elapsed time[sec],Throughput[tps]
1,4764
2,4701
3,4694
4,4827
5,4680
...
56,4829
57,4714
58,4835
59,4835
60,4798
スループットの時系列データは、標準出力に出力された進捗状況のデータと一致しないことがあります。これは負荷テストの並列性を妨げないように、進捗状況を取得する機能で排他制御を行っていないためです。標準出力に出力された進捗状況のデータはあまり正確ではないため、レポートの作成などにはCSVファイルのデータを利用してください。