2009年10月15日木曜日

スワップサイズをゼロにしてはいけない

 先月発売された書籍「Linux-DBシステム構築/運用入門」は、なかなか上々の売れ行きとなっているようです。Amazonではしばらく「1-2ヶ月待ち」の状態が続いてしまっていたのですが、最近になってようやく解消され、容易に入手できるようになっているようです。Amazonの在庫切れ問題がひと段落したところで、これからは書籍のサポート的な情報を書いていくことにします。
 まず、本書を購入された皆さまありがとうございました。結構な数の方がBlogやTwitter等で、この本をほめてくださっていることに大変感謝しています。まだ本自体の認知度が低い(存在自体を知らない顧客も多い)ので、普及活動をしつつ、これからも読者の期待に応えられる記事を書いていきたいと思っています。

 最初は、よく見かけることの多い「メモリ管理」の話題を取り上げようと思います。第12章では、メモリ管理とスワップ領域に関する解説をしています。64ビット機と数十GBクラスの大容量メモリを搭載するのが現在のトレンドになりました。ディスクI/Oの速度はメモリアクセスに比べて極端に落ちますから(第10章参照)、できるだけ多くのデータをメモリ上に置いて高速化をはかるというのがDBチューニングの定石です。多くの場合、メモリを増設することで参照性能だけでなくINSERTなどの更新性能も上がるというのは第9章などで触れている通りです。またダイレクトI/Oを使ってキャッシュ効率を上げることも効果的です。InnoDBならinnodb_flush_method=O_DIRECTを指定すれば良いです。

 メモリ管理の設定でよく見るのが、スワップサイズをゼロにしているケースです。スワップサイズをゼロにすれば、スワップが発生しませんが、これは問題があります。本章で書いているように、プロセスが実メモリを使い切ってしまった場合に、スワップできないのでOOM Killerによって殺されてしまいます。また、このときにハングアップ状態がしばらく続き、挙句の果てに異常終了してしまうためです。単に再起動したとしても、ダイレクトI/Oであればプロセス空間のキャッシュだけでなく、ファイルシステムキャッシュ上に何も載っていない状態からスタートするため、ディスクI/Oが多発して性能が一気に低下します。もちろんDRBD等によるアクティブ/スタンバイ構成でフェイルオーバーするような場合も、フェイルオーバー先にはキャッシュに何も乗っていないため、同じように性能が落ちます。スワップサイズが小さい場合も、それを使い切れば同様にOOM Killerに殺されてしまいます。このため、「スワップサイズをきちんと(物理メモリの半分くらい)取り、ダイレクトI/Oを使い、プロセスよりもファイルシステムキャッシュが優先的にスワップされるようにvm.swappinessをゼロにする」という方法を紹介したというわけです。もちろん、スワップが発生するというのはディスクI/Oが頻発するという意味なので、それを避けるように実メモリの範囲内におさまるようにチューニングするのが大切です。

 なお、MyISAMテーブルなど、ダイレクトI/Oをサポートしていないストレージエンジンでは、RDBMSのプロセスサイズが小さくなり、ファイルシステムキャッシュのサイズが大きくなる傾向にあります。この場合、プロセスだけでメモリ空間を使い切る(OOM Killerによって殺される)ことはまず無いでしょう。

2 件のコメント:

通りすがり さんのコメント...

# echo 2 > /proc/sys/vm/overcommit_memory
しても OOMKiller が動くことがありますか?

Yoshinori Matsunobu さんのコメント...

 overcommit_memory=2のときのメモリ割り当ての上限値は「スワップサイズ + (実メモリサイズ × overcommit_ratio ÷ 100)」なので、overcommit_ratioの設定値次第では、OOM Killerが走る可能性はあります。小崎さんの記事が参考になるかと思います(http://mkosaki.blog46.fc2.com/blog-entry-280.html)。
 スワップをゼロにして、OOM Killerにならない程度に、でも実メモリを有効活用できるようにovercommit_ratioを調整するというのも面倒な話なので、そのくらいならスワップをきちんと取った方が良いだろう、というのが私の見解です。

コメントを投稿