2010年12月9日木曜日

XtraDB 5.5版 性能調整中 (続報)

SSD 更新系処理の性能が明らかに上がったようなので、続報。

SSD で更新系が多い処理で高性能を出すコツ(追加分)

7.innodb_log_block_size (今日作った) をデバイスのブロックサイズに合わせて拡大する。

ご存知とは思いますが(?) InnoDB のトランザクションログの書き込みは 512 バイト単位で行われます。しかし、最近の記録デバイスはそれより大きい記録単位を持っていることが多くなってきました(1K〜4Kバイトくらい)。この時デフォルトの512バイトでは書き込みIOの効率が悪くなっていたようです。
例えば、4Kバイト 単位のデバイスに 512 バイトの書き込みをする場合、他の部分の内容を保持するために、4Kバイト の読み込みの後に 該当個所 512バイト 上書きして、4Kバイト書き込むという動作が必要になります。たとえ、アプリケーションの側からは見えなくても、ドライバやハードウェアの階層でこのような処理が必要となります。4Kバイト 単位IOのデバイスには log_block_size も4KBにするのが最適です。単純に 4KB の読み込みが減るのでトランザクションログ書き込みの効率が上がります。(特に innodb_flush_log_at_trx_commit = 1 の場合は各トランザクションが書き込みを待つため性能が顕著に違うようです。)


このオプションも5.5ベースのXtraDBには実装する予定です。
「もう待てない。是非試したい!」という諸兄は、
bzr branch lp:~percona-dev/percona-server/5.5.7
で開発中バージョン(まだ私の持ち分のパッチだけ(XtraDB + α))が取得できるので、ビルドして試してみてください。


<追記:12月13日>
innodb_adaptive_checkpoint=keep_average と innodb_log_block_size を 5.1系にバックポートしました。次のリリースで多分使えるはずです。

しかし、、、動作確認がてら、BP十分更新系 の負荷をかけたら 5.1 の方が 5.5 よりも 3%くらい速いような。 5.5 はノーマルでは 5.1 より良いのかも知れないが、潜在能力は下がっている。。。ということかも知れない。

2010年11月30日火曜日

XtraDB 5.5版 性能調整中

色々ありましたが、最近、やっと 5.5.x 版のXtraDBを開発中で性能を確認しています。
SSD で試したりもしているのですが、今まで気にしていなかったことが意外に重要なことに色々気づいたので覚え書き。

SSD で更新系が多い処理で高性能を出すコツ

1.Linux native AIO を利用する。 (5.5 共通)

SSDはIOが速いので(?)、今まで通りInnoDB内部のaioを使うとちょっと非効率で、運が悪いと暫く処理されないリクエストが出てくる可能性がありそうです。5.5 ではもう内部のaioにはパッチを当てずにデフォルト通り Linux native AIO を使うことを推奨します。使えない環境の人は、なんとか使えるようにしてからビルドしてください。。。


2.圧縮機能を利用しない。

データページの圧縮機能はSSDの折角速いIOレスポンスを殺します。もしもデータの容量がSSDに入りきらないほど大きく、IOも多いと予想されるなら、普通にRAIDを使った方が速いことが多いでしょう。圧縮機能は結局CPUスケールも悪いので。XtraDBでは、圧縮機能を利用した場合にはいくつかのmutex最適化ができなくなるためそれらは無効になります。(元々InnoDB内部でも block->mutex に当たる物は 全体で 1個なので、CPUスケールは諦めましょう)。この機能は性能を大幅に犠牲にしてディスク上/メモリ上の格納効率を上げる物です。性能を気にするなら利用しないでください。


3.innodb_buffer_pool_instances = 1 。増やさない。

この5.5からInnoDBに実装された buffer pool の個数を増やす機能は、残念ながら現在のところは圧縮機能のCPUスケールを増やすために苦し紛れに実装されたものでしか無いようです。増やすと、buffer pool 毎の last modified age 制御を行う必要があるわけですが、独立して扱うことはできないので flush 制御が増やした分だけ不正確になって更新系のスループットが安定しないようです。上記"2."で 圧縮機能 は使わないわけですからこのパラメータには触らない方がいいでしょう。


4.innodb_flush_neighbor_pages = 0 (XtraDB)(SSD限定)

SSDはランダムアクセスのコストが無いので、纏め書きは無駄なだけです。そのとき、最も書き出す必要がある物を選ばないと(最も古い更新を含むblock)、書き込みIOのスループットを last modified lsn を進めることに効率良く利用することができません。これが意外に重要で、これをやらないと flush 量の見積もりが狂うので、一部の adaptive_[flushing/checkpoint] で長時間のスループットが安定しないようです。


5.innodb_read_ahead = none (XtraDB)(SSD限定)

読み込みも書き込み同様、纏め読みの意味は少ないです。SSDの読み込みIOは十分速いので、先読みの必要はないでしょう。折角 buffer pool に確保している block を無駄に捨てないように無効にしたほうがいいでしょう。


6.innodb_adaptive_checkpoint = keep_average (先週新しく作ってみた。5.5版のXtraDBから実装予定)

新しい方式を作ってみました。自分がSSDで試している限りは他のどの方法よりも最適なスループットに速く落ち着きます。今の"estimate"よりも動作が軽く、flush量もソフトなので、5.5系ではこれをデフォルトにしようを考えています。計算する対象は InnoDB本体の adaptive_flushing と似てるのですが、単位時間当たりの動作回数を増やして細かく制御するようにして、他の flush アクティビティの量も正確に割り出して無駄な flush も抑制します。某所で評判がよければ、5.1系にもバックポートすることになると思います。


と、いうわけで、
近々 5.5系ベース のXtraDBを出すと思います。
性能フリークの方々はお楽しみに!


追記)
あと、SSDではシーケンシャルアクセスの利点が無いので、doublewrite_bufferの影響が如実に出ます。(なぜならデータページの書く量が倍になるわけだから。。。)
イヤなら無効にしましょう。もしくは innodb_doublewrite_file (XtraDBのオプション) で別の書き込みの速いデバイスに doublewrite_buffer 専用ファイルを置きます。