我们正在运行服务器
此服务器定期从外部API生成一定数量的导入,对它们执行一些计算并将这些值保存到数据库中。
大约3个星期前,服务器开始挂起,正如我从NewRelic看到的那样(当ssh'编辑它时) - 随着时间的推移消耗越来越多的内存,最终占用所有可用的RAM,然后服务器挂起。
我已经阅读了一些关于ruby GC如何工作的文章,但仍然无法理解,为什么在凌晨5点30分堆积大小从~2.3M跳到3M,当时还有可用的1M可用堆插槽(默认为GC设置)
所以,问题是:
答案 0 :(得分:3)
如何让Ruby填充空闲堆插槽而不是从OS请求新插槽?
您的图表没有“完整”的保真度。假设GC.stat是由Newrelic调用的,或者恰好恰逢其时。
很可能你的插槽耗尽,堆积增长,而且由于堆积不会缩小,所以你会遇到一堆臃肿的堆。
为了缓解一些痛苦,你可以将RUBY_GC_HEAP_GROWTH_MAX_SLOTS限制为一个理智的数字,类似100,000就可以了,我试图在核心设置一个默认设置。
另外
创建运行的作业和运行时间的持久日志(持续时间等),在作业运行前后收集GC.stat
按队列拆分作业,在一台服务器上运行1个队列,在另一台服务器上运行其他队列,查看哪个队列和哪个作业导致问题负责
使用火焰图或其他剖析工具描述您拥有的各种工作
减少您作为实验运行的并发作业数量,或在某些作业类型之间放置互斥锁。一次1个“工作a”可能是好的,并且20个并发“工作a”一次可能会膨胀记忆。