どうも最近 RHEL/CentOS 5〜6 で Apache & PHP を運用している Web サーバーが、やたらとメモリーを使い果たすような気がする。
もうスワップまで使い果たして OOM Killer が発動してかろうじて kernel だけなんとか生きてるみたいな凄惨な状態にとてもよく遭遇する。なんだかおかしい。
もちろんそれなりに重たい PHP アプリを動かしてるサーバーいるんだけども、ごくごくフツーに WordPress なんかを動かしてるだけのサーバーも、特にそんなにアクセスがあるってわけでもなく、単に Google あたりの bot が連続アクセスしに来てるだけなのにエラいことになってたりする。一昔まえに比べて当たり前のように RAM は潤沢に積んでいるにも関わらずである。
なんだか最近検索エンジンのクローラーがかなり激しい頻度でやってくるようで、それはそれでどうなんだろうと思うのだけども、それにしてもそんなので落ちてしまうのはなかなか情けない。
いろいろと Apache のチューニングなんぞをしてみた結果、これ単純になにかがメモリーリークしてんじゃないかという気がしてきた。
そもそも PHP ってレスポンスを返した時点ですべてのリソースは開放される (セッションデータ $_SESSION はファイル等に永続化して開放される) ハズなので、PHP アプリでメモリーリークさせるのはいちおー処理系仕様上ないハズなので (といってまんざらないわけでもないのがメンドいのだけど)、こらもう Apache か PHP かアプリレベルからは手の出しづらいところにバグがいるんじゃないかと。
で、Apache を prefork で動かしている場合 (RHEL/CentOS はふつーそうなってる)、/etc/httpd/conf/httpd.conf に「MaxRequestsPerChild」という設定値がある。
これは1つの Apache プロセスが何回リクエストを処理したら終了するかというものであり、単純に1回処理するたびに fork したプロセスを終了するのではなく、プロセスを指定回数まで使いまわすことで効率的に処理しようという値である。
これが、RHEL/CentOS 5〜6 だとデフォルトで 4000 に指定されている。つまり当たり前に考えたら1回ごとに終わっても良いハズのプログラムが 4000 回使いまわされているということである。もし仮に本当にメモリーリークがあったとしたら、これは結構ヤバいのではないか?
で、ググってみるとそもそも Apache のデフォルト値は 1000 だそうなので、運用している各サーバーの同値をみんな 1000 にしてみた。
どうやら単純な検索 bot のクロール程度で落ちてしまうというヒドい状態は脱したようである。もし最近の LAMP 環境でやたらと OOM Killer が発動してしまうようであれば、試してみると良いかもしんない。
コメント
まさにこの状態で困っておりました。
記事を参考に設定を変更いたしましたところ、解消いたしました。
大変助かりました、ありがとうございます!