Redis在大型DEL&amp ;;上消耗最大内存。 HMSET函数

时间:2017-06-29 15:16:47

标签: ruby-on-rails ruby heroku memory redis

问题:在预期清除并重建特定的redis键之后,工作人员dynos不会分配内存(直到重新启动dyno)。

我遇到的问题是,我的Heroku worker-dynos在删除和重建 4000 键时,最大内存使用率达到 95%-100%。我有一个预定的重建,每天凌晨4点开始。基于日志我假设键的DEL +键的重建大约需要 ~1490 秒。

Jun 29 04:01:41 app app/worker.2: 4 TID-...io8w RedisWorker JID-...cd2a7 INFO: start 
Jun 29 04:06:28 app app/worker.1: 4 TID-...mtks RedisWorker JID-...bf170 INFO: start 
Jun 29 04:26:32 app app/worker.1: 4 TID-...mtks RedisWorker JID-...bf170 INFO: done: 1203.71 sec 
Jun 29 04:26:33 app app/worker.2: 4 TID-...io8w RedisWorker JID-...cd2a7 INFO: done: 1490.938 sec 

内存将占用最大使用量,直到dyno重新启动(已安排)或我们部署。示例图片:Heroku Memory Usage

这是凌晨4点触发的高级别:

  def full_clear
    RedisWorker.delete_keys("key1*")
    RedisWorker.delete_keys("key2*")
    RedisWorker.delete_keys("key3*")
    self.build
    return true
  end

  def build
    ... rebuilds keys based on models ... 
    return true
  end

  def self.delete_keys(regex)
    $redis.scan_each(match: regex) do |key|
      $redis.del(key)
    end
  end

到目前为止我研究的内容还是我的想法:

  • 在调用redis DEL后,内存没有分配?

  • 是否可以更好地找到匹配并执行批量删除的所有密钥?

  • 我正在使用puma的默认值;配置puma + sidekiq以更好地匹配我们的资源有助于成为最好的开始行动吗? Deploying Rails Applications with the Puma Web Server。重新启动后,内存只有大约30%-40%,直到下一次完全重建(即使在hmsets的高使用率期间)。

  • 我注意到,在dyno重启/休息一天到下一个预定的full_rebuild之后,我的ObjectSpace计数相对较低。

我有什么想法,试图弄清楚是什么导致dynos挂起记忆?似乎是旁边的/正在使用的工作人员dynos重建Redis。

1 个答案:

答案 0 :(得分:0)

<强>解决方案:

我安装了New Relic以查看是否存在潜在的内存膨胀。我们最常用的函数调用之一是进行N + 1查询。修复了N + 1查询并观看我们在New Relic中的60k调用降至~5K。

GC也没有收集,因为它没有达到我们的门槛。稍后可能会有潜在的GC优化 - 但是现在我们的问题已经解决了。

我也向Heroku伸出了他们的想法,这就是所讨论的内容:

  

Dyno上的内存使用将由Ruby VM管理,很可能在密钥重建期间您在内存中保留了太多信息。在重新添加数据之后,您应该考虑释放用于生成键值的内存。

花时间修复N + 1查询肯定有帮助!