LoginSignup
11
8

More than 3 years have passed since last update.

Sidekiqのメモリが増え続ける問題対処

Last updated at Posted at 2021-04-06

メモリが増え続ける

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

11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8