基本性能ベンチマークテスト

ちょこちょこやっていたのを公開する.いつものごとく最初に変なミスで変な結果が出たりしていたが,その後は順調に行った.

今回はちょっとまじめにまとめているので本当はikda.netにUPしたかったが,まだサーバを復旧させていないのでこちらに.新しいHDDは届いたのだけれども,本体カバーをあけるためのドライバーが買いに行かないと無いw

まずは今回のベンチマークの概要から.
gaiyou
こんな感じでJavaプログラム上で作成した多数のスレッドを使ってRDBMSに対して同時に繰り返しアクセス(ラッシュ)を行わせるテストだ.

ちなみに図中で「負荷テストツール」なんて名前でえらそうに鎮座しているのが以前自作したベンチマークツールだ.WEBアプリなどを想定したマイクロベンチマークツールだ.Javaで実装している.

SELECT+UPDATE+COMMITを1つの論理的なトランザクションと仮定し,これを全スレッドで合計で1万回行う.その1万回行うのに経過時間でどれくらいかかったのかと,あと各トランザクションごとのレスポンス時間はどうだったのか(平均値)を測定する.

一般的に,現在のようなマルチプロセス/マルチスレッド実装を持ったOSの上では,1スレッドだけで1万回繰り返すよりも,多数のスレッドで手分けして行わせた方が全体としては効率が良い.

またWEBシステムのようなもののバックエンドとしてRDBMSを使う際には,J2EEサーバやPHPのエンジンなどから同時に複数のリクエストを送ることになるのが普通である.

特にWEBシステムにアクセスが集中した際には,それがRDBMSへの同時アクセススレッド数およびアクセスの繰り返しへと反映されるため,このような実験を行って各RDBMSの特性を知り,RDBMSの選定やハードウェアの選定の際の知識として役立てることが必要だ.

今回の実験で使用したハードウェアスペックを以下に記す。

【サーバ役およびクライアント役をこの1台で】
機種名:IBM ThinkPad T42 (ノートパソコン)
CPU:PentiumM 1.7GHz
RAM:DDR-SDRAM PC2700 1024GB
HDD:60GB 5400rpm ATA100

マシンがへっぽこノートPCなのはこれくらいしか使えるのが手元に無かったため.あとThinkPad X31を追加せずT42だけでやったのはこれくらいのスペックで運用する場合にはマシンが1台であることが多いと思われるためだ(もっと高スペックのマシンでもやってますよね?)

次に,今回使用したプロダクト名およびバージョンを記す

OS:Windows2000Pro SP4およびSuSE Linux9.2 Kernel2.6系
JDK:Sun JDK 1.4.2
RDBMSその1:MySQL 5.0.7 + Connector/J 3.1.8
RDBMSその2:PostgreSQL 8.0.3 + JDBC2実装の8.0.3

MySQLPostgreSQLは今日時点での最新版.実験機であるT42はWindowsSuSEデュアルブートしており,それぞれ同じ実験を行った.従って実験結果はWindows上で行ったものとSuSE上で行ったものの2種類ある.

尚,双方ともチューニングは一切行っていないので,そのつもりで.デフォルト設定=開発側の推奨設定ということで一応.あとチューニング技術でいうと僕の場合はMySQLはチューニングできるけどPostgreSQLのチューニングについては素人だし・・・.

まあ基本性能の検証ということでやってます.1トランザクションが"SELECT+UPDATE+COMMIT"なのもそのためです.

書き忘れました.今回使用しているテーブル定義とテストデータの話が抜けていますね.

CREATE TABLE t1 (c1 int primary key, c2 int);

INSERT INTO t1 VALUES (1, 0);
INSERT INTO t1 VALUES (2, 0);
INSERT INTO t1 VALUES (3, 0);
...
INSERT INTO t1 VALUES (100, 0);

こんな感じの100行のテーブルです.高負荷を与えるテストですので,実際に各アクセス同士が特定の行でぶつかったりとかしやすいように行数は少なくしてます.

言うまでもないが,MySQLの場合には"ENGINE = InnoDB"も付けている.MyISAMPostgreSQLだとアーキテクチャの違いが大きすぎて比較できないので.

SELECTは1から100の中のランダムで選んだものをWHERE句のキーとして使います.そこで取得した値に+1をしてUPDATEをしてCOMMITという感じです.

テスト実行後,100行のテーブルに対して10000回ですから,どの行もc2が100前後の値にまで増加することになります.



さて前置きが長くなったが,そんな感じでやってみた.

まずはWindowsでのスループット.同時アクセス用のスレッドを1から20,40,80,100と増やしていった場合,それぞれの場合にどれくらいのスループットが出るか.
throuput_win
まずPostgreSQLについて.同時アクセス数が少ない場合に最もスループットが高い.グラフ化の関係で省いてしまったが,ピークは同時アクセス数が一桁のときだった.一方で同時アクセス数を増やして再実験を行っていくと,そのたびにスループットが低下していった.

さっきと話違うじゃんとお思いの方,僕もそう思いましたw 何でだかは分からない.

次,MySQLについて.同時アクセス数が小さいとスループットも出ていない.しかし同時アクセス数を増やしていくとほぼ直線的にスループットが向上した.100スレッドくらいまでは順調に伸びる.

次は平均レスポンス時間."SELECT+UPDATE+COMMIT"を1つの単位とした場合に,それぞれがどれくらいのレスポンス時間だったかの平均.
response_win
まあさっきのグラフを反比例にしたようなものだから大体お分かりになるでしょう.

PostgreSQLは同時アクセス数が少ない時にスループットが高かったが,これは平均レスポンス時間が非常に良かったため.しかしながら同時アクセス数が増えるとスループットが逆に下がってしまったことを裏付けるかのように,平均レスポンス時間もやはり同時アクセス数が増えると急激に増加してしまっている.

一方MySQLは同時アクセス数が少ない時のスループットが低かったわけだが,やはりそのときの平均レスポンス時間というのがPostgreSQLに比べるとかなり大きい.しかし同時アクセス数を増やしても平均レスポンス時間が緩やかにしか増加しないため,スレッド数が増えた分だけスループットがぐいぐい上昇したというわけだ.

さて,こうしてみると同じオープンソースRDBMSとはいえ,かなり性能面でも性質に違いがあるね.同時アクセス数が少ないシステムの場合にはPostgreSQLのほうがレスポンス時間が短いので良い.しかし同時アクセス数が大きいシステムの場合にはMySQLのほうが高負荷にも耐えやすく,レスポンス時間の劣化があまり起こらないため最終的にはMySQLのようが良さそうだ.

以上はWindows上で使う場合の話ね.次はLinuxSuSE)の場合.



Linux上でのスループットは以下の結果となった.
throuput_linux
Windows上では互いに長所短所があったPostgreSQLMySQLだったが,Linux上ではMySQLの方がどの場合でも高いスループットを出している.

PostgreSQL自体をWindowsLinuxで比較すると,Windowsのときに見られたような同時アクセス数が少ない時の高性能が発揮されていない.なぜだろう.使用しているライブラリの違いによるもの? 同時アクセス数が20を超えた辺りから毎秒400トランザクション弱で限界に達している.

MySQLの方はWindowsのときと同じように同時アクセス数の増加に比例してスループットも向上.最高で毎秒1800トランザクションくらいまで達している.同時アクセス数が80くらいで頭打ちのもよう.Windowsのときと比べると2-3割性能が良い.その分,早くハードウェアの限界性能に達しているもよう.

平均レスポンス時間は以下の結果となった.
response_linux
レスポンス時間は同時アクセス数が1の場合にはPostgreSQLMySQLともにおぼ同じ.しかし同時アクセス数の増加に対してはMySQLが緩やかにしかレスポンス時間が悪化していないのに対して,PostgreSQLでは急激な悪化が起きている.

PostgreSQLMySQLともにWindowsLinuxとでグラフの形には大きな違いは無い.MySQLではLinux上の方が中盤でのレスポンスが良いが,それはスループットにも現れている通り.PostgreSQLWindows上に比べるとLinux上の方が圧倒的にレスポンスが悪い.

うーん,Windows上では拮抗していたのでLinux上でこれほど大きな違いがでるとは正直予想していなかった.

何かまたまずいことでもやっちゃってるのかな? でもベンチマークの違いといえば使っているJDBCドライバとRDBMSが違うというだけだし.



PostgreSQLはもともとLinux(UNIX)上でのみ開発されていてver8系でWindowsネイティブ対応されたばかりだったから,今回の結果はかなり意外.MySQLWindowsでなんで同時アクセス数が少ないときにPostgreSQLのようなスループットがでないのか,それも謎.

大きく分けるとマルチプロセスによる実装(PostgreSQL)とマルチスレッドによる実装(MySQL)という違いはあるのだけれども,今回の結果は必ずしもこの違いだけがもたらしたものではないと思われる.その辺の謎を引き続き探っていきたいですな.

はぁ〜,なんか肩がいたいな。

サロンパス貼って寝よ。