2017-06-29 112 views
0

问题:在预期清除并重建特定的redis密钥后,工作器dynos不会分配内存(直到重新启动dyno)。Redis在大型DEL&HMSET功能上消耗最大内存

我体验过程中删除在我的Heroku的工人DYNOS均创下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 + sidekiq更好地匹配我们的资源是最好的开始行动吗? Deploying Rails Applications with the Puma Web Server。重新启动后,内存只有大约30%-40%,直到下一次完全重建(即使在大量使用hmset期间)。

  • 我注意到,在dyno重新启动/休息一天之后,我的ObjectSpace计数相当低很多,直到下一个预定的full_rebuild。

任何想法我怎么能去试图找出什么导致DYNOS挂内存?看起来很喜欢/正在使用的工人dynos会重建Redis。

回答

0

解决方案:

我安装了新的文物,看看是否有一个潜在的内存膨胀。我们最常用的函数调用之一是执行N + 1查询。修正了N + 1查询,并在New Relic中观看了我们的60k电话,降至〜5K。

GC也没有收集,因为它没有达到我们的门槛。稍后可能会有潜在的GC优化 - 但目前我们的直接问题已得到解决。

我也接触了Heroku的为他们的想法,这是讨论的内容:

在测功机内存使用情况将由Ruby VM的管理,并且很可能是你保持荷兰国际集团太多密钥重建期间内存中的信息。在数据添加redis之后,您应该考虑释放用于生成键值的内存。

花时间修复您的N + 1查询一定会有所帮助!