web-dev-qa-db-ja.com

Sidekiqは、ワーカーが終了した後、メモリの割り当てを解除しません

JSONクロールを実行する6人のSidekiqワーカーがいます。エンドポイントのデータセットサイズに応じて、1分から4時間で終了します。特に、4時間かかる長いものを見ると、時間の経過とともにわずかなメモリの増加が見られます。

同じワーカージョブを再度スケジュールするまでは、問題ありません。 Sidekiqプロセスを削除するLinuxOOM Killerに遭遇するまで、メモリは割り当て解除されずにスタックします。

メモリリーク? ObjectSpace内のさまざまなオブジェクトの数を確認しました。

ObjectSpace.each_object.inject(Hash.new(0)) { |count, o| count[o.class] += 1 }

そこには実際には増加はなく、ハッシュ、配列などのセットは同じままで、短い増加はガベージコレクターによって一掃され、gc.stat[:count]はガベージコレクターも機能していることを教えてくれます。

労働者が終了した後でも、例えば[Done]がログに記録され、ビジー状態のワーカーはなくなり、メモリの割り当てが解除されません。その理由は何ですか?これに対して何かできますか?ファイナライザーを書きますか?

唯一の現在の解決策:Sidekiqプロセスを再起動します。

私はRuby 2.0.0で、Ruby MRIを使用しています。


JSONの解析には、 Yajl を使用するため、Cバインディングを使用します。ストリーミングされた読み取りと書き込みを適切に実装する唯一の高速JSONパーサーのように見えるので、私はそれが必要です。

30
Guarana Joe

Sidekiqを書いたMike Perhamは、ここでこれに対処しました: http://www.mikeperham.com/2009/05/25/memory-hungry -ルビーデーモン/

tl; dr version:MRIはメモリを返しません。できることは、ヒープを制御することです。これを行うには、 Ruby Enterprise Edition が提案されました。

これが役立つかどうかはわかりませんが、それが状況です-馬の口から直接。

11