Hatena::ブログ(Diary)

SH2の日記 RSSフィード

2009-08-16 データベース負荷テストツールまとめ(2) このエントリーを含むブックマーク

データベース負荷テストツールまとめの第2回です。

前回TPC-Bベース、TPC-Wベースのものから6つのツールをご紹介しました。今回はTPC-Cベースのものについて見ていきたいと思います。

tpcc-mysql

tpcc-mysqlMySQLのコンサル会社であるPercona Inc.によって開発されたベンチマークツールで、TPC-Cをベースとしています。TPC-Cの仕様やtpcc-mysqlについては以前のエントリで詳しく扱っているので、そちらをご覧ください。

TPC-Cは、TPC-BやTPC-Wに比べると仕様が複雑で、試験の設定によって負荷の傾向が変わります。データ量が小さいときはwarehouseテーブルの更新によるロック競合、データ量がやや大きくなるとトランザクションログの書き込みとチェックポイントによるデータファイルの書き出し、さらにデータ量が大きくなるとstockテーブルの参照・更新によるランダムI/O、といったあたりがボトルネックになります。全体としてはストレージにものすごく負荷のかかるベンチマーク仕様です。

TPC-Cは今でも現役で使われており、公式ランキングには各社ハイエンドサーバによる記録がずらりと並んでいます。これらの記録は普通のPCサーバでtpcc-mysqlを実行するのと比べて100倍以上の開きがあるのですが、作りも違うことですしあまり気にしない方が良いかと思います。

TPCC-UVa

TPCC-UVaはPostgreSQL向けに実装されたTPC-Cベースのベンチマークツールです。スペインバリャドリッド大学で学生の卒業研究として作られたもののようです。UVaというのはバリャドリッド大学の略号ですね。

PostgreSQLは専門外なので今回試してはいないのですが、ソースコードや論文を見る限りは筋が良さそうです。TPC-Cは測定を行うと注文データが増えていってしまうのに対しそれを元に戻すための機能があるなど、全体的に親切な作りになっています。

jTPCC

f:id:sh2:20090815114633p:image

jTPCCはスウェーデンヨーテボリ大学の方が作られたTPC-Cの実装です。Javaで書かれているためOSを選ばないこと、OracleMySQLPostgreSQLに対応していることが特長です。

どうやらマニュアルが無いようなので、ソースを読んで使い方を調べました。メモしておきます。

  • ユーザ、データベースを作成する
  • sql/mysql/ct_bench_mysql.sql を実行してテーブルを作成する
  • tpcc.propertiesを環境にあわせて編集する
database.mysql.db=scott
database.mysql.driver=com.mysql.jdbc.Driver
database.mysql.host=localhost
database.mysql.port=3306
database.mysql.connector=jdbc
database.mysql.user=scott
database.mysql.pwd=tiger
  • jTPCCPopulationクラスを起動してデータロードを行う。設定ファイルを指定するtpcc.file、RDBMSを指定するproductシステムプロパティが必要。スケールファクタを引数で指定する。ログがlogs/traces.logに出力される
$ java -Dtpcc.file=tpcc.properties -Dproduct=mysql org.jtpcc.population.jTPCCPopulation 1
  • jTPCCConsoleまたはjTPCCSwingクラスを起動して測定を行う。jTPCCPopulationと同様に二つのシステムプロパティが必要。jTPCCSwingでは接続数や試験時間などをGUIで設定することが可能。ログはreportsディレクトリに出力される
$ java -Dtpcc.file=tpcc.properties -Dproduct=mysql org.jtpcc.jTPCCSwing
  • jTPCCStatisticsクラスを起動して試験結果をグラフ化する
$ java org.jtpcc.graph.jTPCCStatistics reports/jtpcc_session_mysql_20090815024913.txt mysql

一見良さそうなのですが、このツールは問題ありです。最大の問題は、サーバよりクライアントの方が負荷が高いことです。Java HotSpot Server VMを使っても、クライアントの方が対MySQL比で3倍ほど高負荷になります。これでは最大性能を測ることができません。

以下のように毎回SQLを組み立てているところが良くないですね。Statementオブジェクトを作っては捨て作っては捨てという動作になるので、端的に言うとJavaのGarbage Collectionベンチマークになってしまっています。またStatementオブジェクトを使うと毎回SQL文の解析を行うことになるため、特にOracleの場合は解析処理の負荷が高すぎて正常な測定にならないでしょう。きちんとPreparedStatementを作って使いまわすようなコーディングをする必要があります。

query = new StringBuffer();
query.append("SELECT count(c_id) AS namecnt");
query.append(" FROM customer");
query.append(" WHERE c_last = \'");
query.append(c_last);
query.append("\' AND c_d_id = ");
query.append(d_id);
query.append(" AND c_w_id = ");
query.append(w_id);

Hammerora

f:id:sh2:20090815114632p:image

HammeroraはOracleエンジニアSteve Shaw氏によって書かれた負荷テストツールです。Steve Shaw氏はPro Oracle Database 10g Rac on Linuxの共著者でもあります。

TCLで負荷テストツールなんて書けるのかと思ったのですが、どうやら書けるようです。TPC-Cの各トランザクションがストアドプロシージャで実装されているため、クライアント側の負荷が十分低く抑えられています。またトランザクションを呼び出すルーチンをユーザ側に見せていて、自由にカスタマイズできるようになっています。TCLが読み書きできれば任意の負荷をかけることもできるようです。

Oracleのエキスパートが作っているだけあって、インデックスをきちんと張っていたり、データロードが並列にできるようになっていたりとツボをおさえた作りになっています。

MySQLには2008年にリリースされたバージョン2.2から対応しています。MySQLの場合でもTPC-Cの各トランザクションはストアドプロシージャで実装されており、MySQLにおけるストアドプロシージャの貴重な利用例と言えるかもしれません。ただ、MySQLの測定結果は間違っているように見えます。今回使った測定用PCで79,044tpmも出るはずはないのですが…。

ODBC Bench

f:id:sh2:20090815192943p:image

ODBC Benchは米国ソフトウェア企業OpenLink Softwareによって提供されているベンチマークツールです。OpenLink Software社はUNIX/Linux用のODBCドライバマネージャ、iODBCの提供元でもあります。ODBC BenchはiODBCのデモンストレーション用ソフトウェアといった位置付けではないかと考えられます。

Oracle 11gとの組み合わせで試していたのですが、残念ながら負荷をかけるところまでたどり着けませんでした。あとで再挑戦するときのためにメモを残しておきます。

  • unixODBCを使う

まずiODBC 3.52.6-1ではそもそもOracle 11gに接続することができませんでした。iodbctestコマンドで接続テストをすると、どうしてもクライアントが異常終了してしまいます。そのためやむを得ずunixODBCを使うことにしました。

  • unixODBCの最新版を使う

unixODBCを使った場合にも問題があって、CentOS 5.3付属のunixODBC 2.2.11-7.1ではOracle 11gには接続できません。Oracle 11gに接続するにはunixODBCの2.2.12以降が必要です。今回は最新版の2.2.14をダウンロードしてビルドしました。またODBC Benchが静的ライブラリを要求するため、configureスクリプトに--enable-staticオプションを指定する必要がありました。

$ ./configure --enable-static
$ make
$ sudo make install
$ ./configure --with-unixodbc --without-iodbc
$ make
$ sudo make install
  • ~/.odbc.iniを編集する
[ORA111]
Driver      = /opt/oracle/product/11.1.0/db_1/lib/libsqora.so.11.1
ServiceName = ORA111

ここまで作業を行った結果が最初のスクリーンショットです。データロード時になぜかORA-12899が出てしまい、残念ながらこれ以上先に進めませんでした。おそらく、Oracle 11gにあわせたプログラムの修正が必要なのではないかと思います。

Benchmark Factory(R) for Databases

f:id:sh2:20090815220340p:image

Benchmark Factoryは今回ご紹介する中で唯一の商用ソフトウェアです。対応RDBMSベンチマーク仕様の多さはさすが商用ソフトウェアといったところです。試用版を使ってみてなかなか良さそうだとは思ったのですが、ソフトウェアライセンス契約上その内容については書けないので、カタログベースの紹介にとどめておきます。

DBT-2

DBT-2はOSDL(Open Source Development Labs)が開発したTPC-Cの実装です。DBT-1と同様に当初はSAP DBをターゲットとして開発され、その後PostgreSQLへの移植が行われました。またDBT-1と違ってMySQLにも対応しており、この部分は当時のMySQL ABの協力のもと実装されているようです。

SAP DBを除くと、DBT-2では以下の3パターンの構成で測定を行うことができます。

  1. PostgreSQLでストアドプロシージャを使う (--with-postgresql)
  2. MySQLでストアドプロシージャを使う (--with-mysql)
  3. MySQLで直接SQLを発行する (--with-mysql --enable-nonsp)

ただ、どうもconfigureスクリプトバグがあるようです。今回使用したバージョン0.40では2番の構成がとれず、--with-mysqlに加えてどのオプションを指定しても3番の構成になってしまいます。MySQLでストアドプロシージャを試したい場合は、configureスクリプトに以下のパッチを当ててみてください。

*** configure   2007-02-12 03:07:19.000000000 +0900
--- configure.new       2009-08-16 16:54:33.000000000 +0900
***************
*** 5696,5702 ****
  if test "${enable_nonsp+set}" = set; then
    enableval=$enable_nonsp; NONSP="yes"
  else
!   NONSP="no"

  fi

--- 5696,5702 ----
  if test "${enable_nonsp+set}" = set; then
    enableval=$enable_nonsp; NONSP="yes"
  else
!   NONSP=""

  fi

全体的な手順は漢(オトコ)のコンピュータ道: DBT-2によるベンチマーク手順が参考になると思います。実際に測定を行う際は、run_workload.shなど周辺のスクリプトも環境に合わせてカスタマイズする必要があります。

オススメは…?

ここまでいろいろご紹介してきましたが、TPC-Cの実装は品質にちょっと難のあるものが多いです。この中から選べと言われたら、私なら以下のようにします。

  • MySQLの場合:tpcc-mysql、DBT-2
  • MySQL以外の場合:自分で作る (選んでませんが)

TPC-Cは仕様書を素直に読み込むとストアドプロシージャを使うことになるのですが、実際のシステムでストアドプロシージャを利用することはそれほど多くありません。そういった意味で、ストアドプロシージャを用いたHammerora、DBT-2は測定結果の解釈が少々難しくなると思います。jTPCC、ODBC Benchはきちんと動かないのでこのままでは使えません。TPCC-UVaは試していないので評価を保留します。Benchmark Factoryはお値段次第ですね。

TPC-Cは、オープンソースで複数RDBMSに対応した品質の良いものがないところが課題かもしれません。例えばMySQLPostgreSQLの比較をしたいと思っても、TPC-Cのカテゴリでは今のところ方法がありません。

続きます

というわけで第2回はTPC-Cベースの負荷テストツールを見てきました。次回はその他のTPCベンチマーク仕様とその実装を確認していこうと思います。それではまた。