メモリが増え続ける
webコンテナとは別にworker用のコンテナを立ててsidekiqを動かしているという構成で、データ量の大きなオブジェクトを作成し、S3にアップロードしたpathをクライアント側に返す処理になっていた。
重たい処理を実行するたびにメモリが開放されずに膨張し続けて、たて続けに実行するとすぐにアラートが飛んでくるようになっていた。
これのせいでトラウマでSidekiqに抵抗が。。。
この人と状況似ていて参考にした。デザイン性の乏しいブログにこそ有益な情報がある
http://blog.jiikko.com/133
プロセスをフォークして切り捨てる
フォークしたプロセスで処理を完結させるときれいにメモリ膨張が抑えられて処理終了とともにメモリが開放されるようになった。
1番最初にできたのがこれ
class Test
include Sidekiq::Worker
def perform
pid = Process.fork do
# 処理内要
end
Process.waitpid pid
end
end
これだと開発環境でActiveRecordまわりでエラー吐いていたので調べてみるとプロセス別にコネクションを用意してあげないといけないらしい。
マルチプロセス部分が終了したらメインプロセスで再接続。で出来上がったのが以下。
ほぼこれのまま 感謝 => https://gist.github.com/danieldbower/842562
def process_fork
# tracking if the op failed for the Process exit
config = ActiveRecord::Base.remove_connection
pid = Process.fork do
begin
ActiveRecord::Base.establish_connection(config)
# This is needed to re-initialize the random number generator after forking (if you want diff random numbers generated in the forks)
srand
# Run the closure passed to the fork_with_new_connection method
yield
rescue Exception => exception
puts ("Forked operation failed with exception: " + exception)
ensure
ActiveRecord::Base.remove_connection
Process.exit!
end
end
ActiveRecord::Base.establish_connection(config)
#return the process id
Process.waitpid pid
end
使う時はこんな感じ
class Test
include Sidekiq::Worker
def perform
process_fork do
# 処理内容
end
end
end
他に参考にしたやつ
https://cloud6.net/so/ruby-on-rails/1480000
https://qiita.com/naotospace/items/61c7a5a4e44473fa1e21