2013年11月29日金曜日

allocatorを変えてMySQLをベンチしてみた

MySQL Performance Blogにtcmalloc/jemallocを使うとパフォーマンスが良くなるという記事があるので、気になって手元の環境でも計測してみました。

環境

CPUIntel Xeon CPU E5-2620 x 2
OSCentOS 6.4 64bit
MySQLMySQL 5.6.14
sysbenchSysbench 0.4.12
jemallocjemalloc 3.4.1
tcmallocgperftools 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使用率やレイテンシにも着目するべきですが、それは今後の課題とします。

2013年11月28日木曜日

Fedora最新技術情報&Systemd勉強会に参加してきました

Linux女子部主催のFedora最新技術情報&Systemd勉強会に参加してきました。

Fedora最新技術情報

講師は藤田稜さん

Fedora最新技術情報といいつつRHEL7のお話でした。いくつか気になった点をピックアップします。

xfsがデフォルトになるかも

RHEL7ではxfsをデフォルトファイルシステムにしたいそうですが、まだ安定性やメモリ消費量に難があり、技術的な観点から決定はしていないそうです。

「RHEL 4, 5, 6 の初期出荷でファイルシステムの破損バグを仕込んだ実績があるので、今からxfsに切り替えたら絶対何か踏む」という声も。

iptablesからfirewalldへ

今までファイアウォールはiptablesを使っていましたが、標準でfirewalldを使うように変更します。従来のiptablesとは排他利用になります。戻すことはできますが、基本的にはfirewalld推奨とのこと。設定を読み込み直すときにreloadしてもセッションが切れなくなっているそうです。

またそれに伴いNetworkManagerが必須となるようで、今まで殺していた人はうまく付き合ってくださいとのことでした。

OpenLMI導入

OpenLMIという管理系機能の共通インタフェースがあるそうなんですが、それがRHEL 7.0GAには入るんじゃないかということ。従来例えばファイルシステムだけ取っても fdisk, gparted, lvm, mkfs など様々なコマンドがバラバラにあったものが、整理され統合されるんだとか。

その他

その他は、systemd入りますよ(後述)、Linux Containerのフルサポート、pNFSのクライアントサポート、実はSELinux enforcedでしかQAしてないので、permissive/disabledはテストしていませんというお話などが聞けました。

大きくはやはり管理系の仕組みがsystemd, OpenLMI, firewalld, NetworkManagerというものに置き換わるのが大きな変更点のようです。「カーネルランドは同じだけどユーザーランドは違うOSと言っても良いほどの変更」と言われていました。

Systemd徹底入門

講師は中井悦司さん

今回のお話のスライドはslideshareにアップロードされていて、時間の都合で省略されたところも含めて詳しく解説されています。ここで細かい話を書いても実際スライドのほうが詳しいので、私が疑問に思った点や補足を中心に記述します。

SysV Init から systemdへ

従来は SysV Init が /sbin/init に存在して最初にpid=1として起動していましたが、代わりに/usr/bin/systemdが起動します。今までは単なるシェルスクリプトが/etc/inittabに定義された順に実行されていたので、シリアルにしか実行できず性能も悪かったものが、systemdではそれぞれのタスクを細かくunitという単位に定義して依存関係と前後関係に基づいて並列的に実行し、起動速度を高速化します。

systemdを作ったのはレナートさんで、彼のblogにどうしてsystemdを作ったのかが載っているので、英語ですがぜひ読んでみてくださいとのこと。systemd の大きな目的は4つあって、

  • システム起動時間の短縮
  • システム構成の動的変更に対応
  • プロセス停止処理を標準機能として提供
  • デーモンの実行環境を制御

です。

依存関係と前後関係

SystemdではRequire/WantedByという依存関係と、Before/Afterという前後関係にもとづいてunitの実行順が決定されます。ここで依存関係というのは単に必要だということを記述するだけで、実際にはその中では平行にunitが実行されていきます。そのため、例えばhttpdが起動する前にDNSが起動しておいてほしい、というようなことはすべて前後関係として記述するようです。

アプリケーションサービスなどもsystemd管理下へ

init だとクラッシュした時の再起動がないので、よくアプリケーションサービスなどを supervisord や daemontools を使って別に起動させていた方も多いと思いますが、基本的には systemd がこれらも含めてすべて見るようにするのが理想的ということです。cgroupを使ってプロセスツリー全体のリソースも管理でき、ログ管理機能もあるのでsystemd管理下に置くほうがシステム全体として整合性も取れるような印象です。

また従来はdaemonizeすることが多かったところsystemdではdaemontoolsのようにforegroundで実行するのが基本的なスタイルになるようです。Typeを変えればforkするデーモンにも対応可能です。

便利そうなコマンド

systemctl status (unit名)すると、関連するプロセスの一覧やログの抜粋が表示される。

systemctl list-units すると、現在有効なunitの一覧が表示され、起動に失敗しているものもひと目でわかる。

systemctl list-dependencies (unit名) すると、依存関係がツリー状に表示される。

manページを読もう

作者のレナートさんがドキュメント魔らしく、manページが大変充実しているので、困っても困らなくてもmanページを読めば良いとのことでした。

感想

systemdという巨大な仕様のものを入れることにRed Hat社内でも議論があったそうですが、結局のところ SysV Init がイケてないし置き換えることは必要で、より良いデーモン管理のため導入することにしたそうです。話を聞くと使う分にはちゃんと動きそう、だけども何でもsystemdにやらせるのは「Unixぽくない」と感じます。

浸透のためにはDebianやGentooもsystemdに移る必要があると思うし、もし今後initが複数使われるのであればソフト作者はsystemd用、upstart用というふうにわけて起動スクリプトを用意しなければいけなくなるかもしれません。そういうのは望ましくないので、なんとか一本化してほしいなぁと思いました。