物理メモリが不足したらpumaを自動で再起動

Ruby on Rails

概要

  • pumaがどんどんメモリを食っていってしまう。同様に、sidekiqもたくさんメモリを食ってしまっている。
  • GCしても減らない。
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
ObjectSpace.each_object(ActiveRecord::Relation).each(&:reset)
GC.start
ObjectSpace.each_object(ActiveRecord::Relation).each(&:reset) GC.start
ObjectSpace.each_object(ActiveRecord::Relation).each(&:reset)
GC.start
オレンジはswap used. 減るときは再起動しているタイミング。
  • 物理メモリが80%以上使われていたらpumaを再起動するスクリプト書いた。

Puma

*/15 * * * * /path/to/restart_if_high_memory.sh >> /tmp/restart_if_high_memory.log 2>&1
view raw crontab hosted with ❤ by GitHub
#!/bin/bash -x
set -e
HOME=/path/to/app
cd $HOME
# returns 1 if physical memoryusage is higher than 80%
usage=`free -m | sed -n 2p | awk '{ printf("%d", ($3/$2)/0.8) }'`
if [ $usage -ge 1 ]; then
cd path/to/current && kill -USR2 `cat tmp/pids/puma.pid`
fi

Sidekiq

*/15 * * * * /path/to/restart_if_high_memory.sh >> /tmp/restart_if_high_memory.log 2>&1
view raw crontab hosted with ❤ by GitHub
#!/bin/bash -x
set -e
HOME=/path/to/home
cd $HOME
PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
# returns 1 if usage is higher than 80%
usage=`free -m | sed -n 2p | awk '{ printf("%d", ($3/$2)/0.8) }'`
if [ $usage -lt 1 ]; then
exit 0
fi
cd path/to/current
# sidekiq process can be multiple so find process id and kill then start corresponding to the process.
list=`ps axu|grep sidekiq|grep -v grep|awk '{print $2}'`
for pid in $list; do
kill -TSTP $pid
sleep 10
kill -TERM $file`
sleep 10
RAILS_ENV=production bundle exec sidekiq -d
done

導入結果

  • swapにまで食い込まなくなりました。

Comments

  1. matsubokkuri より:

    OSの方で最適化がかかって、物理メモリが80%未満になって、swapされるような感じもするから発動タイミングは要調整。だけど、ほとんどの場合は問題無し。

  2. matsubokkuri より:

    こちらによって根本解決しました。
    https://tech.studyplus.co.jp/entry/2019/09/09/094140

タイトルとURLをコピーしました