ruby on rails - Unicorn Memory Usage filling up almost all the RAM -


new relic process snapshot

there 3 problems here:

1) unicorn seems steadily filling ram, causing me remove workers manually.

2) unicorn seems spawning additional workers reason, although have specified fixed number of workers (7 of them). partly causing ram buildup, causing me remove workers manually.

3) 0 downtime deployment unreliable in case. picks changes, gateway timeouts. each deploy becomes stressful situation.

i don't using monit, because kills workers without waiting workers finish serving requests.

so, normal? other people deploy using unicorn have same problem ram grows uncontrollably?

and workers number of workers spawned not match number of workers defined?

the other alternative unicorn worker killer, trying out after reading unicorn eating memory.

tiny update:

enter image description here

so came point new relic telling me memory 95%. had kill worker. interestingly, killing worker brought memory down quite lot, seen graph below.

what's that?

for reference, here's unicorn.rb , unicorn_init.sh. love tell me there's mistake in there somewhere.

unicorn.rb

root = "/home/deployer/apps/myapp/current" working_directory root pid "#{root}/tmp/pids/unicorn.pid" stderr_path "#{root}/log/unicorn.stderr.log" stdout_path "#{root}/log/unicorn.log"  listen "/tmp/unicorn.myapp.sock" worker_processes 7 timeout 30  preload_app true  before_exec |_|   env["bundle_gemfile"] = '/home/deployer/apps/myapp/current/gemfile' end  before_fork |server, worker|   # disconnect since database connection not carry on   if defined? activerecord::base     activerecord::base.connection.disconnect!   end    old_pid = "#{root}/tmp/pids/unicorn.pid.oldbin`"   if old_pid != server.pid     begin       sig = (worker.nr + 1) >= server.worker_processes ? :quit : :ttou       process.kill(sig, file.read(old_pid).to_i)     rescue errno::enoent, errno::esrch     end   end   sleep 1 end  after_fork |server, worker|   # start database connection again in worker   if defined?(activerecord::base)     activerecord::base.establish_connection   end    redis.current.quit   rails.cache.reconnect end 

unicorn_init.sh

#!/bin/sh set -e  # feel free change of following variables app: timeout=${timeout-60} app_root=/home/deployer/apps/myapp/current pid=$app_root/tmp/pids/unicorn.pid cmd="cd $app_root; bundle_gemfile=/home/deployer/apps/myapp/current/gemfile bundle exec unicorn -d -c $app_root/config/unicorn.rb -e production" as_user=deployer set -u old_pin="$pid.oldbin"  sig () {   test -s "$pid" && kill -$1 `cat $pid` }  oldsig () {   test -s $old_pin && kill -$1 `cat $old_pin` }  run () {   if [ "$(id -un)" = "$as_user" ];     eval $1   else     su -c "$1" - $as_user   fi }  case "$1" in start)   sig 0 && echo >&2 "already running" && exit 0   run "$cmd"   ;; stop)   sig quit && exit 0   echo >&2 "not running"   ;; force-stop)   sig term && exit 0   echo >&2 "not running"   ;; restart|reload)   sig usr2 && echo reloaded ok && exit 0   echo >&2 "couldn't reload, starting '$cmd' instead"   run "$cmd"   ;; upgrade)   if sig usr2 && sleep 2 && sig 0 && oldsig quit       n=$timeout     while test -s $old_pin && test $n -ge 0           printf '.' && sleep 1 && n=$(( $n - 1 ))     done     echo      if test $n -lt 0 && test -s $old_pin           echo >&2 "$old_pin still exists after $timeout seconds"       exit 1     fi     exit 0   fi   echo >&2 "couldn't upgrade, starting '$cmd' instead"   run "$cmd"   ;; reopen-logs)   sig usr1   ;; *)   echo >&2 "usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"   exit 1   ;; esac 

you appear have 2 problems: 1) have errors in coordination of graceful restart causing old unicorn workers , old master stick around; 2) app (not unicorn) leaking memory.

for former, looking @ before_fork code, appears you're using memory-constraining approach the example config however, have typo in .oldbin file name (an extraneous back-tick @ end) means never signal old process because can't read pid non-existent file.

for later, have investigate , drill. in app caching semantics accumulate data on time; examine use of globals, class-vars, , class-instance-vars can retain data references request request. run memory profiles characterize memory use. can mitigate memory leakage killing workers when grow bigger upper limit; unicorn-worker-killer makes easy.


Comments

Popular posts from this blog

css - Which browser returns the correct result for getBoundingClientRect of an SVG element? -

gcc - Calling fftR4() in c from assembly -

.htaccess - Matching full URL in RewriteCond -