ruby-on-rails - Redis 在大型 DEL 和 HMSET 函数上消耗最大内存

标签 ruby-on-rails ruby heroku memory redis

问题:在预期清除和重建特定的 redis 键后,worker dynos 不分配内存(直到重新启动 dyno)。

我遇到一个问题,我的 Heroku worker-dynos 在删除和重建大约 4000 键期间达到 95%-100% 最大内存使用率。我有一个预定的重建计划,每天凌晨 4:00 开始。根据日志,我假设 key 的 DEL + key 的重建大约需要 ~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 计数相对较低。

有什么想法可以着手找出导致测功机挂起内存的原因吗?似乎孤立在一边/正在使用的 worker 测功机正在重建 Redis。

最佳答案

解决方案:

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

GC 也没有收集,因为它没有达到我们的阈值。稍后可能会有潜在的 GC 优化——但现在我们的紧迫问题已经解决。

我还联系了 Heroku 了解他们的想法,这就是讨论的内容:

Memory usage on the Dyno will be managed by the Ruby VM, and is likely that you're keep ing too much information in memory during the key rebuild. You should look into freeing memory used to generate the key-values after the data has been added redis.

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

关于ruby-on-rails - Redis 在大型 DEL 和 HMSET 函数上消耗最大内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44829071/

相关文章:

javascript - Rails Assets 管道挂起

ruby-on-rails - 事件管理员 : sorting on multiple columns

Javascript 保持页面状态 - 最佳实践?

ruby-on-rails - 从我的 .each 循环中获取流氓迭代

apache - 如何使用自定义域在 heroku 上启用完美前向保密?

php - 推送被拒绝,未能检测到 set buildpack heroku/php

django - Heroku/Django 部署 : why am I getting an error 500 with successful deploy and static collection?

ruby-on-rails - 在计算机重启时运行 Rails 项目

javascript - 如何在 Rails 3 应用程序中插入 CKEditor 插件?

ruby-on-rails - 如何为 Jruby Oracle 连接设置 SSL?