この前、Heroku環境にunicorn-worker-killerを入れてみたという記事を書いて、1日くらい経って、「うんうん、大丈夫だなー」と思っていたのだが、数日後にスワップが大量に発生してR14のエラーが大量に発生していた。未だに原因はよくわかっていない。
検証用の環境で、再度アクセスをいろいろとしてみたけれど、時間が経過&継続的なアクセスがないとこの大量スワップ発生現象は起きないみたいで、どうにも検証しづらい。
現在の検証環境では、unicorn-worker-killerのメモリ使用上限を200〜250MB、worker数を4にしていたのだが、今更ながらだが、unicornのmasterプロセスのメモリのことをあんまり意識してなかった。
参照URL:Secrets to Speedy Ruby Apps On Heroku
WEB_CONCURRENCYの計算はシンプルで、
WEB_CONCURRENCY = (Dynoのメモリ量 – unicornのmasterプロセスのメモリ使用量) / unicornのworkerプロセスのメモリ使用量
であるということなので、それを計算したかったのだが(どうせHerokuのStandard2Xなら2〜4であるとは思うが)、Herokuの環境で1workerプロセスあたりどれくらいメモリを使っているか、masterプロセスがどれくらいメモリを使っているかを調べる方法がいまいちわからなかった。
仕方ないのでとりあえずローカルでpsコマンドを打って確認してみた。まずはforeman経由でunicornを立ち上げる。
foreman start
その後、psコマンド。
ps aux | grep unicorn
何度かローカルのRailsアプリにアクセスして、unicornのworkerにメモリを食わせたのち、またps aux | grep unicornしてみる。
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND t-oko 30267 0.7 0.0 2451204 720 s001 S+ 4:02PM 0:00.00 grep unicorn t-oko 28033 0.0 1.2 2698140 202204 s000 S+ 3:26PM 0:09.07 unicorn master -p 3000 -c ./config/unicorn.conf.rb t-oko 28059 0.0 1.2 2736768 203616 s000 S+ 3:27PM 0:04.48 unicorn worker[2] -p 3000 -c ./config/unicorn.conf.rb t-oko 28058 0.0 1.4 3312496 228016 s000 S+ 3:27PM 0:06.30 unicorn worker[1] -p 3000 -c ./config/unicorn.conf.rb t-oko 28057 0.0 1.4 3315000 231100 s000 S+ 3:27PM 0:07.29 unicorn worker[0] -p 3000 -c ./config/unicorn.conf.rb
RSSを見る限りだとmasterプロセスが200MBくらい、workerプロセスも200〜225MBくらいっぽい。まぁ負荷をかけたものじゃないので、本来はもっと増えそうに思う。というところで、WEB_CONCURRENCYに設定できそうな値は、
WEB_CONCURRENCY = (1024 – 200) / 250
くらいかなぁと思うのでやっぱり3くらいが妥当に思えた。
ところで参考URLを読んだときに、worker-killerを使うような場合はおそらくWEB_CONCURRENCYの値が大きすぎるんだ!と書いてあったので、unicorn-worker-killerを使うのは本当は良くないのかもしれない…。