处理作业后,Sidekiq不释放内存

Viv*_*thy 5 ruby garbage-collection ruby-on-rails sidekiq docker

我在rails应用程序上有一个ruby,我们通过sidekiq在后台验证来自巨大excel文件(200k记录)的记录.我们还使用docker,因此为sidekiq使用了一个单独的容器.当sidekiq启动时,使用的内存大约为120Mb,但随着验证工作者的开始,内存达到500Mb(经过大量优化后).问题是在处理作业后,内存使用率保持在500Mb并且永远不会被释放,不允许添加任何新作业.我在每10k记录后以及在作业完成后使用GC.start手动启动垃圾收集,但仍无法提供帮助.

Pas*_*cal 5

这很可能与 Sidekiq 无关,而是与 Ruby 如何从操作系统分配内存以及将内存释放回操作系统有关。

很可能内存由于碎片而无法释放。除了优化程序(按块处理数据而不是将其全部读入内存)之外,您还可以尝试调整分配器或更改分配器。

关于 Ruby/Memory 这个特定问题已经有很多文章,我真的很喜欢 Nate Berkopec 的这篇文章:https : //www.speedshop.co/2017/12/04/malloc-doubles-ruby-memory.html深入到所有细节。

简单的“解决方案”是:

使用 jemalloc,或者如果不可能,则设置MALLOC_ARENA_MAX=2

更复杂的解决方案是尝试进一步优化您的程序,以便它首先不会加载那么多数据。

通过切换到 jemalloc,我能够将项目中的内存使用量从 12GB 削减到 < 3GB。该项目涉及大量导入/导出,并且写得相当糟糕,但它很容易获胜。