実は最近、個人的にサーバーマシンを借りるという機会があった。そのマシンに搭載されているCPUコア数は合計48である!大事なのでもう一度いう。日本語でいう。48CPUコアだ!一昔前なら数千万円もしたスペックだろうが、最近は実にリーズナブルにお求めいただけるようである。(価格についてはふせておく。)このマシンには2.2GHzのOpteron 6174が4つ搭載されている。つまり、ひとつのパッケージに12個のコアが格納されているのだ。これはすごい。いや、むしろどうしてこうなった?!というべきか。そのようなマシンを目の前にすると時代はメニイコアに向かっているんだなあと実感せざるを得ない。
今後、CPUがどんどんメニイコアに向かう流れはさけれない。コアを増やさなければCPUの性能が(システム全体としての性能が)向上しないからだ。CPUの演算回路に対して半導体素子をたくさん投入しても、素子数に対する性能向上の比率は大して高くない。一方、コア数を増やせばその分確実に並列処理が可能になる。もちろん、マルチスレッドモデルではロックが、マルチプロセスではプロセス間通信がオーバーヘッドを生じるので、メニイコアのマシンでそのCPU性能を生かし切るというのは、易しい課題ではないのである。
MySQLも例外ではなく、如何にしてマルチスレッド性能を向上させるかということに取り組んできた。だが、以前のバージョンでは思うようにマルチスレッド性能が向上して来なかったが、しかし着実に進歩を続けている。今回借りることが出来た48コアのマシンは、その事を証明するための絶好の機会である!そこで、今回はMySQL 4.1、5.0、5.1、5.1+InnoDB Plugin、5.5の性能をそれぞれ測定してみることにした。用いたベンチマークソフトはsysbenchであり、同時接続数を1、4、8、16、32、48、64、96、128、256、512、1024と変化させてそれぞれのRead-Only/Read-Writeの性能を測定した。そのときのグラフが以下である。(縦軸はTPS、横軸はスレッド数だ。)結果を単純に並べたグラフと、スレッド数と結果をプロットしたものを準備した。
追記/注意:一部の方からベンチマーク結果の画像を見ることが出来ないという報告を受けました。本ブログに画像が表示されていない人はこちら(Google Docs)からどうぞ。
いかがだろう。一見にしかずとはこのことではないだろうか。バージョンが上がるごとに着実にスケーラビリティが向上している様子が手に取るようにわかるだろう。これからのメニイコア時代の備えも万全である。
ちなみに、本ベンチマークはすべてのバージョンにおいて同じ条件で行った。利用したコンフィギュレーションは以下のとおり。バージョンによってパラメーター名が異なるものがあるが、それらについてはコメントを記述している。
[mysqld] max_connections=2000 max_prepared_stmt_count=1000000 character_set_server=utf8 table_open_cache=4000 # 5.0 以前は table_cache に table_definition_cache=1000 # 5.0 以前はカット read_buffer_size=128K read_rnd_buffer_size=128K join_buffer_size=128K sort_buffer_size=128K open_files_limit=20000 innodb_buffer_pool_size=20G innodb_log_file_size=1G innodb_log_buffer_size=10M innodb_flush_method=O_DIRECT # 5.1のみInnoDB Pluginの設定を追加 # ignore-builtin-innodb # plugin-load=innodb=ha_innodb_plugin.so;innodb_trx=ha_innodb_plugin.so;innodb_locks=ha_innodb_plugin.so;innodb_lock_waits=ha_innodb_plugin.so;innodb_cmp=ha_innodb_plugin.so;innodb_cmp_reset=ha_innodb_plugin.so;innodb_cmpmem=ha_innodb_plugin.so;innodb_cmpmem_reset=ha_innodb_plugin.so
OSのほうでは、カーネルの起動オプションとしてelevator=deadlineを、/etc/security/limits.confにおいてnofileおよびnprocを100000に設定した。それ以外、OSの設定はすべてデフォルトのままである。(ファイルシステムはext4。)
追記: sysbenchのコマンドオプションは次の通り。
t=1\
rows=1000000\
read_only=on\
sysbench\
--test=oltp\
--db-driver=mysql\
--oltp-table-size=$rows\
--mysql-user=msandbox\
--mysql-password=msandbox\
--mysql-host=127.0.0.1\
--mysql-port=5550\
--mysql-db=sb\
--max-time=60\
--oltp-read-only=$read_only\
--max-requests=0\
--num-threads=$t\
run
こんな感じでパラメーターを変化させつつループを回し、計測を行った。
せっかくなので、同じベンチマークをより新しいカーネルを使って測定するべく、Ubuntu 10.10-Alpha3を使用して測定した。Fedora 13ではカーネルのバージョンが2.6.33、Ubuntu 10.10(コードネーム Maverick Meerkat)では2.6.35となっている。
なんと驚くべきことに、2.6.35のほうがほぼすべての結果において2.6.33を上回っている。Linuxカーネルも着実に進化しているということだろうか。必ずしも、新しいカーネルの方が良い結果になるとは言えないが、OSが変わると性能も変わる可能性があるということを意識しておいたほうがいいだろう。(今回はたまたまかも知れない。ベンチマークは水物なのだから。)
次のグラフはシングルスレッド性能の比較である。MySQL 4.1のスコアがあまり良くない。「昔のほうが軽かった」という記述をよく見かけるが、真実はこうだ!
次のグラフはオマケ。すべての結果を一度に表示したもの。Read-onlyに比べてRead-writeがどの程度落ちるのかが一目瞭然である。
今回利用したサーバーマシンは4つのソケットがあり、ローエンドのモデルと比較するとかなり豪華であるように見える。ローエンドのマシンをずらっと並べる「スケールアウト」戦略に基づいたシステムでは、48個ものコアを搭載したマシンが使われることはまだないだろう。だが、時代はもうすぐそこまで来ている。たくさん搭載されたコアを使い切れないと生き残れないというシビアな時代が!である。MySQLはそのような時代を乗り切るための準備を着々と進めているのである。
今回のベンチマークではまだ48個のコアを使い切っていない。シングルスレッド性能の48倍にはまだまだ及ばないからだ。実は、MySQL 5.5ではマルチスレッド性能をさらに高めるためのオプションが導入されているのだが、今回はあえて過去のバージョンとの性能を比べるため、新しいオプションは使用しなかった。もし、再びCPUコアをたくさん搭載したマシンを借りられる機会があれば、次はMySQL 5.5で導入されたパラメーターをチューニングして、パフォーマンスの限界に挑戦してみたいと思う。
それではみなさん、まだまだ残暑は厳しいけれども体調など壊さぬようご注意を。ごきげんよう!!
コメントリクエストいただいてしまったので。
返信削除SysBenchのOLTPテストですが、oltp-dest-typeという乱数の生成ルーチンを選ぶオプションがあって、これがデフォルトだとspecialになっていると思います。
specialだとSELECTの対象レコードがかなり中央に偏る設定になっていて、rowsをいくら増やしても意味がないくらい偏ります。
そのためデータアクセスを集中させてInnoDBをいじめたい場合はspecialかgaussian、rowsをある程度増やして万遍なくアクセスさせたい場合はuniformにするのがおすすめです。
Perconaの人たちはuniformでテストしています。 http://bit.ly/cpZXBI
あとは仮想化した場合の性能が見たいですねー
sh2さん、
返信削除コメントありがとうございますw
なるほど。確かにoltp-dist-typeは指定するべきでしたね。ただ、uniformでテストしたperconaのベンチマークでは16スレッド時に3000程度のスコアであるのに比べて、こちらは48スレッド時に6000オーバーまで出ています。Uniformにするともう少し伸びるかも知れませんね。次回は両方はかってみたいと思います。
あと、次回はauto-inc有り無しの場合の差などもテストする予定です。