MySQLのベンチマークを用いたIntel X25-M SSDの評価

X25-MSSDで検索してくる方が非常に多いので、本ブログ内のSSD関連記事をリストしておきます。



先週末IntelSSDX25-Mが突然7,000円ほど値下がりしたので、ついに我慢できず手を出してしまいました。初めてのSSD導入です。
SSDベンチマーク記事は国内・海外問わずたくさんありますが、実際にデータベースを乗せて計測した記事はそれほど多くありません。そこで、先日ご紹介したtpcc-mysqlを用いてベンチマークテストを行ってみました。
データベースサーバ

負荷クライアント

データベース構成

  • スキーマ構成 : TPC-C準拠
  • データベースサイズ : 3.6GB (40 Warehouses)
  • ストレージエンジン : InnoDB
  • 同時接続数 : 1, 2, 4, 8, 16, 24, 32, 48, 64

MySQLのパラメータは本エントリの末尾をご参照ください。
X25-Mですが、MySQL Performance Blog漢(オトコ)のコンピュータ道で解説されているように、内部のライトキャッシュがバッテリなどで保護されていません。そのためデータベースとしてCOMMITされたデータを保証するためには、ライトキャッシュをOFFにする必要があります。

今回は業務用途を想定してinnodb_flush_log_at_trx_commit = 1、sync_binlog = 1とデータの保護を優先した設定にしています。しかし、X25-MのライトキャッシュをONにしたままではこれらを設定しても意味がありませんので注意してください。ただし、ベンチマークとしては純粋に面白そうなので、ライトキャッシュONにおける測定も行っています。
さっそく測定結果を見てみましょう。

横軸はデータベースに対する同時接続数、縦軸は1分間あたりに処理したnew-orderトランザクションの数です。new-orderトランザクションが全てのトランザクションに対して占める割合はおよそ43%ですので、実際にはこの2倍強のトランザクションがデータベースに対して発行されていることになります。
それぞれの構成でピーク値を見ると、HDDが同時接続数4のときで396 tx/m、ライトキャッシュOFFのX25-Mが同時接続数16のときで1,778 tx/m、ライトキャッシュONのX25-Mが同時接続数32のときで4,362 tx/mとなっています。つまりX25-Mを利用するとHDDに対してライトキャッシュOFFでも4.5倍、ライトキャッシュONの場合は(本来は反則ですが)11.0倍の性能を得られるという結果になっています。カタログスペックからは確かに予想できた数値なのですが、実際に目の前で動いているのを見ると圧巻です。しかもこれを無音でやってのけるのですから気持ち悪いくらいです。
CPU使用率は以下のようになっています。ここから先のグラフはそれぞれの構成でピーク値のデータをピックアップしたものになっています。

今回はinnodb_buffer_pool_sizeを1GBに設定した上でテストデータを3.6GB用意しています。TPC-Cはテストデータにまんべんなくアクセスするので、これぐらいのバランスだと基本的にI/Oバウンドの負荷になります。HDDとライトキャッシュOFFのX25-MではCPUを使い切っておらず、確かにI/Oバウンドになっていることが分かります。I/Oバウンドになった場合はそれ以上同時接続数を増やしてもほとんどスループットが上下しないところも特徴の一つです。
一方ライトキャッシュONのX25-MではCPU使用率が80%を超えており、明らかなCPUバウンドです。X25-Mが速すぎるためCore2 Duo 2.0GHzとMySQL 5.1.32ではその性能を引き出しきれていません。ライトキャッシュONの構成ではCPUをもっと速いものに取り替えればさらにスループットが上がると考えられます。Core i7が欲しくなりますね。
次に、ディスクI/Oの様子を見てみましょう。まずは読み込みです。


指標値として1秒間あたりの読み込み量(MB/sec)とI/O回数(IOPS)を挙げています。結果的にグラフの形は同じですが、通常データベースのオンライントランザクション性能を分析するときはIOPSの方を見ます。今回はWindowsなのでパフォーマンスモニタからデータを引っ張ってきています。Linuxであればiostat -xコマンドでr/sの列をチェックします。
HDDの場合は回転待ち時間とシークタイムという機械的な制約があるため、IOPSはどうしても伸びません。単純化して回転待ち時間だけを考えると、7,200rpmのHDDは1秒間に120回転となり、目的のデータがくるまで平均半回転するとみなすと1秒間あたりのI/O回数は240回が限界ということになります。HDDのRead IOPSにこの後出てくるWrite IOPSを足すとほぼぴったり合います。
また読み込み量をI/O回数で割ると、12.5 × 1,024 ÷ 798 = 16.0となるので、1回のI/Oあたり平均16KB読み込んでいることが分かります。これはInnoDBのページサイズ16KBと一致しています。このことからも、MySQLサーバはInnoDBのデータファイルに対して(シーケンシャルではなく)ランダムアクセスをしているということが分かります。
TPC-Cのワークロードでは在庫テーブルの更新処理がI/Oの大半を占めます。注文処理に応じて在庫数の更新を行うUPDATE文があるのですが、在庫テーブルはTPC-Cの中でもっとも大きいテーブルであるため基本的にはメモリに収まりません。インデックス・ツリーの大半はメモリに載るとしても、ツリーの末端にある実際のレコードのデータを読み込むために、多くの場合ディスクI/Oを1回行うことになります。
このようにメモリに収まらない大きなテーブルがあると、インデックスを張っていてもどうしてもSQLあたり1回のI/Oが発生してしまいます。そして、HDDのIOPSによって1秒間あたりに処理できるSQL数の上限が決まってしまう、というのがI/Oボトルネックの典型的なパターンの一つになっています。これを解決するには、テーブルサイズを超えるメモリを搭載するか、テーブルを縦に分割してサイズを小さくするか、RAIDを組んでIOPSを上げるか、あるいはテーブルを横に分割してサーバ分散するか、といった対策を打つことになります。
ひるがえってX25-Mを見てみると、言うまでもありませんが機械的な駆動部分がありませんのではるかに高いIOPSが出ます。今回の測定結果ではライトキャッシュOFFで323、ライトキャッシュONで798です。4桁のIOPSが出てもよいと思ったのですが、どうもライトキャッシュOFFは書き込み、ライトキャッシュONはCPUが足を引っ張っているようです。
続いて書き込みのI/Oを見てみましょう。


これも2つのグラフで形は変わりません。Write IOPSはHDDで145、ライトキャッシュOFFのX25-Mで729、ライトキャッシュONのX25-Mで1,801となっています。読み込みよりもIOPSが高くなっていますが、これはTPC-Cのトランザクションにはただ読むだけという処理が全体の9%しかなく、残りの91%が何らかの更新を行うこと、更新の際には更新データそのもの以外にもバイナリログとInnoDBトランザクションログを書き込む必要があることが原因となっています。TPC-Cのワークロードは非常に更新が多く、一般的なウェブアプリケーションとはかなり特性が異なります。
ライトキャッシュOFFのX25-Mにおける性能ボトルネックは、このWrite IOPSが729というところだと考えられます。これでももちろん単体のHDDよりははるかに速いのですが、15,000rpmのSAS HDDを4本程度使ってRAID 1+0を組めば追いつく数値です。一方ライトキャッシュONでの性能はまだ限界に達しておらず、底が見えません。このレベルの性能をHDDで出そうとすると、だいたいhp MSA2012saクラスのストレージ製品が必要になります。家は建ちませんが車が買えます。この抜群の性能を見てしまうと、できればライトキャッシュはONにしつつ何らかの機構でデータを保護できないものかと思います。

このように、これまで数百万円クラスのストレージ製品が必要とされていた性能を3万円のSSDが達成してしまうのですから、Intel SSDおそるべしです。ライトキャッシュの保護や信頼性・運用性の条件をクリアして、競争力のある価格でALL SSDの業務用ストレージ製品を出すベンダが現れれば、一気にデータベースはSSDを使うのが当たり前という時代に変わると思います。何もしないストレージベンダはいくつか潰れるかもしれませんね。
最後に、測定で使用したmy.cnfを載せておきます。

[mysqld]
datadir = C:\mysql-5.1.32-win32\data    # SSD
# datadir = D:\mysql\data               # HDD

# character set ##################################
character_set_server = utf8
collation_server = utf8_bin             # 大文字と小文字を区別する

# InnoDB #########################################
default_storage_engine = InnoDB
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 1      # 信頼性を優先
innodb_thread_concurrency = 0
innodb_buffer_pool_size = 1G            # 32bitのため少なめ
innodb_log_buffer_size = 8M
innodb_log_file_size = 256MB

# binary log #####################################
log_bin = vostro-bin                    # バイナリログ有効
binlog_format = MIXED                   # READ COMMITTEDのためROWで動作する
binlog_cache_size = 1M
sync_binlog = 1                         # 信頼性を優先

# slow query log #################################
slow_query_log = 1
long_query_time = 0.5

# connections ####################################
max_connections = 256
thread_cache_size = 8

# other performance related parameters ###########
table_open_cache = 768                  # 9テーブル×64接続を確保
sort_buffer_size = 8M
max_allowed_packet = 16M

# etc ############################################
transaction_isolation = READ-COMMITTED
console = 1

このエントリはWBC決勝の再放送を見ながら書きました。やはりイチローは格が違った。それでは。