traPtitech/traQ

elasticsearch周りでメモリリークしている

Nagarei opened this issue · 0 comments

func (bi *bulkIndexer) init() で確保したメモリが解放されていない。
./service/search/es_sync.goで、bulkIndexerのcloseをしていないのに、途中でreturn break continue があり、リークしている。

if count == 0 {
if more {
continue
}

traQ上での議論

  • 裏どりしないで滅茶苦茶適当なこと言うんですけど、もっと全体的に書き換えてしまっても良い気がしています。関数内で1つのbulkIndexerを使いまわすとか(deferを書きやすいし)
    • できたらよさそうですけど、1回あたりのbulk indexに上限があったので頑張らないといけなそうですね
      それでいうと、今tickerで1分ごとに回してるけど、ライブラリに一定間隔での実行の機能が備え付けられてるので、もしかしたらそこに上限もうまく扱ってくれる機能があるかもです
      ↑依存の方向変えずにやるの難しそうだけど
    • BulkIndexerConfigFlushBytesとかFlushIntervalがある
  • 多分なんだけど、forループの中の1回のinsert操作を関数に切り分けられるといいんじゃないかな…と思ってる
    1回の関数実行で必ず1つのbulkInsertが生成・実行される用にすると、deferでCloseするのがやりやすく、可読性も上がると思う
    できるだけ引数少なくなるように範囲絞れると良さそう
    • 軽く見ただけで言っているのですが、無名関数でくるんでdeferするのが楽だったりしませんか?
    • 編集距離はそれが少ないと思いますが、ネスト深いし名前つけてしまっても良い気もします(好みの範疇)
      Close = insertの挙動、どちらかと言えばClose = flushなので、バッファ系の標準的な挙動として理解はできる
  • まぁとりあえず対処するだけなら、count==0 のif文の前にClose処理持ってくれば解決はできそう