4月からペパボで働いているわけですが、前々から噂できいていたメモリリークの問題について、ペパボではわりと大規模かつ高負荷な環境でngx_mrubyを使ってくれているのでその環境を見ながらメモリリークを改善してみました。
状況的には、16時間動かしていると導入している環境のngx_mrubyを組み込んだnginxが1GBぐらいメタボっていました。
実装や幾つかの調査情報をみつつ、以下の2点においてメモリリークが発生していました。
- mrubyが例外をあげて5xx系のエラーコードを返す時
- mruby_set系のディレクティブを使っている時
上記のそれぞれにおいて、C側で生成したオブジェクトをarenaに登録したまま、不要になったにも関わらずarenaからオブジェクトを除外してGCさせるように処理できていなかった事が問題でした。
これらを、ほぼ同等の改修によってmrb_gc_arena_save()
とmrb_gc_arena_restore()
でC側のオブジェクトをGCさせるようにしたことで、メモリリークを改善することができました。
結果的に、同等の時間で1GBぐらいになっていたnginxのメモリ使用量が約半分の500MBぐらいになりました。この改修によって、メタボになるせいで行っていた運用を減らす事ができそれが直接サービスの改善にも繋がったので、結果的に管理者にもサービス利用者にもメリットのある改善になりました。めでたしめでたし。
というわけで、ペパボではさらにmod_mrubyやngx_mrubyをヘビーに使っていくようなので、それに合わせて大規模運用環境で浮き彫りになった問題を今後も粛々と改善していきたいと思います。
mrubyによるミドルウェア制御等、この辺りに大変興味があって自分も一緒に仕事したいと思った方は是非是非お声掛け下さい。