MySQL Performance Blogにtcmalloc/jemallocを使うとパフォーマンスが良くなるという記事があるので、気になって手元の環境でも計測してみました。
環境
CPU | Intel Xeon CPU E5-2620 x 2 |
---|---|
OS | CentOS 6.4 64bit |
MySQL | MySQL 5.6.14 |
sysbench | Sysbench 0.4.12 |
jemalloc | jemalloc 3.4.1 |
tcmalloc | gperftools 2.1 |
MySQLのmax_connectionsは2048に設定しました。innodb_file_formatはBarracudaで、Buffer poolは56GBを確保し、buffer pool instanceは32に設定しました。
測定内容
sysbench の OLTP テストを下記のようなコマンドで走らせました。
for t in 16 32 64 128 256 512 1024; do sysbench --test=oltp --oltp-table-size=1000000 --mysql-user=benchuser --mysql-password=benchuser --db-driver=mysql --num-threads=$t --max-requests=200000 --oltp-read-only run; done for t in 16 32 64 128 256 512 1024; do sysbench --test=oltp --oltp-table-size=1000000 --mysql-user=benchuser --mysql-password=benchuser --db-driver=mysql --num-threads=$t --max-requests=200000 run; done
jemalloc の nodirty というのは "MALLOC_CONF=lg_dirty_mult:-1" という環境変数をセットしたものです。これは3.2以降性能がベンチマークによっては劣化することがあるというので気になって測りました。
tcmalloc + large page は、my.cnf に large-page を付けてMySQLを起動したものです。read/writeは取り忘れたのでreadのみです。
なお試行回数は1回で、ベンチマークを2回走らせた2回目の値です(平均とか取ってません)。測定のたびにmysqlを再起動し、cleanup/prepareを実施しました。
allocatorの差し替えは/etc/init.d/mysqlにexport LD_PRELOAD=...を記述する方法を取りました。ロードされていることは/proc/{pid}/mapsを見て確認しました。
測定結果
read/writeに関しては、測定のばらつきが大きく、実行するたびに2割程度は差が出る結果になりましたのであまり信頼の高い結果ではありません。jemallocはスレッド数が1024の場合にのみ、glibc mallocより22%程度高速という結果になりました。tcmallocは16-32スレッドの場合は最大2割遅く、64スレッド以上では1割程度高速でした。
readは比較的安定した結果が出ました。jemallocはglibc mallocと比較し5%程度遅くなりました。tcmallocはglibc mallocと同等または高速で、最大3%程度の差が出ました。
tcmallocでlarge-pageを有効にしても有意な差は見られませんでした。これは今回のデータサイズが小さく、TLBサイズが変わってもヒット率が変わらなかった可能性があります。
考察、まとめ
MySQL Performance blogに掲載されていたような、256スレッド以上ではglibcが遅くなるという現象は見られませんでした。また、jemallocがtcmalloc/glibc mallocとくらべて低速であるという結果になりました。これは設定によるのか、ベンチマークの種類によるのかはわかりませんが、必ずしもjemallocやtcmallocに差し替えることによってMySQLの性能が向上するとは言えない結果になりました。ただしtcmallocはglibc mallocより遅いことはなかったので、差し替えることによってデメリットはメモリの消費量が増える以外は生じないので、メモリに余裕があるのであれば検討してもよいかと思いました。
元のblogでは64スレッドを超えると1万transactions/secを超えているのに対し、こちらではたかだか5000スレッドしか出てません。向こうは32スレッドあるのでこちらより性能が良いのですが、それでも少し性能が低い気がします。ですので、何か設定がまずいのか、それともallocatorが実は差し替わっていない可能性も残っています。
transactions/secだけではなく、CPU使用率やレイテンシにも着目するべきですが、それは今後の課題とします。