メモリが膨張し続けるSidekiqプロセス(ジョブ)と立ち向かう

文脈

10MBくらいのJSONを生成してs3にアップロードするSidekiqジョブがあるのだが、このジョブを実行するとSidekiqプロセスのメモリ使用率が膨張したままになり、監視アラートが飛んでくる、という問題があった。実行頻度は1週間に数回。
このジョブは、ファイルオブジェクトにJSON断片をappendしているだけなので、実際にメモリ上に必要なオブジェクトは大したことがないはずなのだけど、実際はそうなっていなくてJSONの断片がメモリ上にすべて乗っているように見える。

立ち向かう

  • (おまじない)ループ中で手動GCをする
  • 生成オブジェクトをへらすためにselectするカラムを絞る
  • (おまじない)ActiveRecordのクエリキャッシュを無効にする
  • ジョブ内でforkして、forkしたプロセスでJSONを作成する
  • jemallocを使う

ということをやった。
jemallocはすごくよくてメモリの膨張を抑えてくれているし、forkすることで大量に抱えたオブジェクトを強制的に捨ててくれるようになったので監視アラートが飛んでこなくなった。

おわり