この章では、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.0.0.jarを任意のディレクトリに配置し、環境変数CLASSPATHを設定します。Windowsの場合はsetコマンドで環境変数を設定することができます。
> dir
C:\jdbcrunner のディレクトリ
2009/12/21 01:10 <DIR> .
2009/12/21 01:10 <DIR> ..
2009/12/21 00:10 2,799,105 jdbcrunner-1.0.0.jar
> set CLASSPATH=jdbcrunner-1.0.0.jar
Linuxなどでbashを使用している場合は、exportコマンドで設定します。
$ export CLASSPATH=jdbcrunner-1.0.0.jar
ツールの起動クラスはパッケージなしのJRです。追加のオプションなしで実行すると、簡単な使い方が表示されます。
> java JR
JdbcRunner 1.0.0
スクリプトファイルが指定されていません
usage: java JR <script> [options]
-autoCommit <arg> オートコミットモードを有効化または無効化します (デフォルト : true (有効))
-connPoolSize <arg> コネクションプールの物理接続数を指定します (デフォルト : nAgents)
-debug デバッグモードを有効にします (デフォルト : false)
-jdbcDriver <arg> JDBCドライバのクラス名を指定します (デフォルト : com.mysql.jdbc.Driver)
-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
01:09:31 [INFO ] > JdbcRunner 1.0.0
01:09:31 [INFO ] [Config]
Program start time : 20091221-010931
Script filename : test.js
JDBC driver : com.mysql.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
01:09:33 [INFO ] [Warmup] -9 sec, 3265 tps, (3265 tx)
01:09:34 [INFO ] [Warmup] -8 sec, 4649 tps, (7914 tx)
01:09:35 [INFO ] [Warmup] -7 sec, 4667 tps, (12581 tx)
01:09:36 [INFO ] [Warmup] -6 sec, 4695 tps, (17276 tx)
01:09:37 [INFO ] [Warmup] -5 sec, 4638 tps, (21914 tx)
01:09:38 [INFO ] [Warmup] -4 sec, 4695 tps, (26609 tx)
01:09:39 [INFO ] [Warmup] -3 sec, 4741 tps, (31350 tx)
01:09:40 [INFO ] [Warmup] -2 sec, 4845 tps, (36195 tx)
01:09:41 [INFO ] [Warmup] -1 sec, 4748 tps, (40943 tx)
01:09:42 [INFO ] [Warmup] 0 sec, 4765 tps, (45708 tx)
01:09:43 [INFO ] [Progress] 1 sec, 4770 tps, 4770 tx
01:09:44 [INFO ] [Progress] 2 sec, 4660 tps, 9430 tx
01:09:45 [INFO ] [Progress] 3 sec, 4665 tps, 14095 tx
01:09:46 [INFO ] [Progress] 4 sec, 4690 tps, 18785 tx
01:09:47 [INFO ] [Progress] 5 sec, 4289 tps, 23074 tx
...
01:10:38 [INFO ] [Progress] 56 sec, 4637 tps, 264567 tx
01:10:39 [INFO ] [Progress] 57 sec, 4659 tps, 269226 tx
01:10:40 [INFO ] [Progress] 58 sec, 4824 tps, 274050 tx
01:10:41 [INFO ] [Progress] 59 sec, 4678 tps, 278728 tx
01:10:42 [INFO ] [Progress] 60 sec, 4750 tps, 283478 tx
01:10:42 [INFO ] [Total tx count] 283479 tx
01:10:42 [INFO ] [Throughput] 4724 tps
01:10:42 [INFO ] [Response time (minimum)] 0 msec
01:10:42 [INFO ] [Response time (50%tile)] 0 msec
01:10:42 [INFO ] [Response time (90%tile)] 0 msec
01:10:42 [INFO ] [Response time (95%tile)] 0 msec
01:10:42 [INFO ] [Response time (99%tile)] 0 msec
01:10:42 [INFO ] [Response time (maximum)] 5 msec
01:10:42 [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 のディレクトリ
2009/12/21 01:10 <DIR> .
2009/12/21 01:10 <DIR> ..
2009/12/21 00:10 2,799,105 jdbcrunner-1.0.0.jar
2009/12/21 01:10 6,133 jdbcrunner.log
2009/12/21 01:10 65 log_20091221-010931_r.csv
2009/12/21 01:10 566 log_20091221-010931_t.csv
2009/12/21 01:09 116 test.js
log_20091221-010931_r.csvと末尾に「_r」がついたCSVファイルは、レスポンスタイムの度数分布データです。レスポンスタイムごとにトランザクション実行数が出力されます。
Response time[msec],Count
0,283334
1,75
2,1
3,3
4,51
5,15
log_20091221-010931_t.csvと末尾に「_t」がついたCSVファイルは、スループットの時系列データです。
Elapsed time[sec],Throughput[tps]
1,4771
2,4660
3,4665
4,4694
5,4283
...
56,4636
57,4658
58,4826
59,4678
60,4749
スループットの時系列データは、標準出力に出力された進捗状況のデータと一致しないことがあります。これは負荷テストの並列性を妨げないように、進捗状況を取得する機能で排他制御を行っていないためです。標準出力に出力された進捗状況のデータはあまり正確ではないため、レポートの作成などにはCSVファイルのデータを利用してください。