Kahuaのメモリリークの調査と対策
[Sumibi.org]を「さくらのクラウド」に引越した後もKahuaのメモリリーク問題が解決していなかった。 急遽RAM容量の大きなサーバインスタンスに変更して運用回避していたが、このまま無意味なコストの垂れ流しを止めるべく調査した。 やっと解決したので調査結果を書いておこうと思う。 このまま放置するとコスト削減額はなんと月額4000円にもなるので、ちょいと見過ごすわけにはいかないのである。
概要
[Sumibi.org]のサイトは1台のサーバインスタンスで構成されており、[Sumibi.org]の日本語変換サービスと、Wikiシステムの[OldType]が同居している。 メモリリーク問題は[OldType]のほうにあり、使っているKahuaフレームワークのworkerのプロセスが膨張していくというのが問題だった。 Kahuaのworkerがメモリを圧迫し、結果的に[Sumibi.org]の変換レスポンスが重くなるという現象が発生していた。
膨張のペース
[OldType]を1日程度放置すると、Kahuaのworkerプロセスが1個につき1.2GByteまで膨張する。 常時2個のworkerを起動する設定にしていたため、3GByteのRAMでは足りず、swapを2G Byteほど侵食し、[OldType]のサイトがエラーを返すようになる。 GoogleやYahooのクローラが来て、サイトのページを一巡するとworkerは1.2GByteあたりになる。なぜか1.2GByte以上には膨張しないようだ。
回避策
さくらのクラウドの料金シミュレーション ページより
原因究明までの間、「さくらのクラウド」のインスタンスを3GByteから6GByteにして20日間ほど回避した。
6GByteならリークしていても問題なく運用できていた。ランニングコストを除いては問題ない(笑)
しかし、お金さえ払えば、問題を先送りして普通に運用できるのはクラウドサービスの良いところである。
対策
workerを1時間に1回リスタートするスクリプトを動かして対応した。 このスクリプトはOT_SITEにサイトバンドルのパスさえ設定すれば、どんなKahuaアプリでも使えるはず。 hourly restarter for Kahua workers(restarter.sh)
結果
RAM 3GByteでも約1GByteの余裕を持って運用できるようになった。
青い線はリザルトコード。一番下側に張りついている線は、”200 OK”のリクエスト。
“404 Not Found”が大量に出るのは、Kahuaフレームワークが非ブラウザが動的生成されたURLを叩いた時だ、自動的に404にしてくれているようだ。頼もしい。
restarter.shをリスタートすると、freeメモリのグラフがキザギザになる。うまくいっているようだ。
restarter.shを一定期間止めておいて、再度開始する実験をしたが、freeエリアがいっきに復活している。うまくいっているようだ。
まとめ
[OldType]もしくはKahuaのworkerプロセスが膨張するが、workerプロセスの定期的restartをかければ問題なく運用できる。 なぜworkerがそんなにメモリを消費するのかという原因追求はしていない。 対処療法的ではあるが対策し、無用なランニングコストを抑えることができた。
コメント by shiro:
workerプロセスは継続をたくさんハッシュテーブルに登録してますが、それのexpireがうまくいってないのかな?
workerが掴んでる継続の一覧をモニタできるようにしてみるといいかも。ちょっと見てみます。
コメント by kiyoka:
通常運用で、workerが膨張するのでshiroさんの予想は当たっているかもしれません。
OldTypeはコンテンツページの1行毎に継続が生成されているので、開放されないとするとすぐにworkerが肥大しそうですね。
以前shiroさんもchatonで同様の現象について、他に同じような現象を見た人はいませんかというような書き込みをされていたと思いますが、まさにこれがそうかも。
同じ原因だといいですね。よろしくお願いします。
コメント by shiro:
workerプロセスは継続をたくさんハッシュテーブルに登録してますが、それのexpireがうまくいってないのかな?
workerが掴んでる継続の一覧をモニタできるようにしてみるといいかも。ちょっと見てみます。