2017-06-03 74 views
3

我们运行红宝石请求时,有很多免费的堆插槽

  • Sidekiq 4.2.9
  • 轨4.2.8
  • MRI 2.1.9

这是一个服务器更多的内存服务器定期从外部API中产生一定量的导入,对它们执行一些计算并将这些值保存到数据库中。

大约3个星期前,服务器开始挂起,就像我从NewRelic看到的那样(当ssh发现它时) - 它随着时间消耗越来越多的内存,最终占用所有可用内存,然后挂起服务器。为什么在~5:30 AM堆大小从〜2.3M跳到3M时,仍然有1M空闲堆插槽可用(GC设置为默认)

enter image description here

类似的行为,3:35 PM: enter image description here

所以,问题是:

  1. 如何让Ruby填充空闲堆槽而不是从操作系统请求新插槽?
  2. 如何让它释放免费的堆槽到系统?
+0

值得一读:https://blog.heroku.com/incremental-gc – Anthony

+0

你使用什么服务器?美洲狮?独角兽?瘦?生产中的webrick? –

+0

@JoshBrody,我们的Puma服务器很好,我说的是sidekiq服务器 –

回答

3

如何让Ruby填充空闲堆槽而不是从操作系统请求新插槽?

您的图形没有“完整”保真度。假设GC.stat是由Newrelic调用的,或者恰好在恰当的时候调用了很多。

这是非常可能的,你跑完槽,堆增长,因为堆不缩小在Ruby中,你有一个有点臃肿的堆坚持。

为了减轻一些痛苦,你可以将RUBY_GC_HEAP_GROWTH_MAX_SLOTS限制为一个合理的数字,比如100,000这样做,我试图游说在核心设置默认值。

而且

  • 创建的运行时间,他们跑(持续时间等)工作的一个持续日志,之前收集GC.stat和作业后运行

  • 由分散你的工作队列,运行1队列中的服务器和其他排队的另一个上,看哪个队列和工作是负责这个问题你已经使用flamegraph

  • 简介各种工作或其他分析工具

  • 减少作为实验运行的并发作业数量,或者在特定作业类型之间放置互斥量。有可能一次“工作一次”是好的,而一次20个并发的“工作”会使内存膨胀。

+0

谢谢,会试试看写结果 –

+0

一定要升级到ruby 2.4之前的东西,有很多gc bugs全部高达2.3的方式可能会导致无保证的增长。 –