【问题标题】:Redis filling up memory fast, running --bigkeys free it upRedis 快速填满内存,运行 --bigkeys 释放它
【发布时间】:2020-01-17 13:43:27
【问题描述】:

一个月前,Redis 突然开始快速填满服务器内存。为了调试问题,我们运行了 redis-cli --bigkeys,令我们惊讶的是所有使用的内存都被释放了。

我们有一个由 6 个节点组成的集群,分别是 3 个主节点和 3 个从节点,每个主节点数据库大约 15GB。每个节点都存储在一个专用的盒子中,每个盒子有 64GB。 Redis 每天两次填满 64GB 的整个内存。我们有一个每天两次运行 redis-cli --bigkeys 的 cron 来释放使用的内存。

可能是什么原因?

谢谢。

【问题讨论】:

  • 如果 redis-cli --bigkeys 破坏了你的记忆,很可能是过期的密钥尚未被驱逐。检查您的 eviction policy 和 maxmemory 设置。 INFO 的输出可能有助于识别问题。如果可能的话,用更多信息更新问题
  • 请参阅redis.io/commands/expire#how-redis-expires-keys,了解为什么 redis-cli --bigkeys 中的 SCAN 会强制驱逐
  • 我的驱逐策略是 noeviction 并且 maxmemory 设置为 0。 1) 为了防止它被填满,我应该设置一个 maxmemory 和一个驱逐策略来删除过期的键还是仅仅 maxmemory 就足够了? 2) 推荐的驱逐政策是什么?在阅读了驱逐政策页面后,我更倾向于使用 allkeys-random。 3) 在驱逐未过期的密钥之前,是否有任何驱逐策略首先从过期的密钥开始? @LeoMurillo

标签: redis redis-cluster


【解决方案1】:

除非您每天运行两次 redis-cli --bigkeys,否则您会收到 OOM command not allowed 错误。

如果是这种情况,您可能有很多和/或带有EXPIRE 的大键,并且不断添加。从内存中删除过期的密钥:

  • 被动:当您尝试访问它并且发现密钥超时时。 这就是redis-cli --bigkeys 为您提供帮助的方式,它强制对所有键空间进行被动删除。
  • 主动:每 100 毫秒,它会尝试从内存中删除过期的密钥 at random,每个周期在其上投入的时间不会超过 1 毫秒,直到它估计剩余的过期密钥少于 25%。逻辑不是那么简单,请参阅activeExpireCycle

因此,在您的情况下,活动过期无法赶上这一切。

根据您的评论,maxmemory=0maxmemory-policy=noeviction。您可能需要考虑设置一个maxmemory 值,并将maxmemory-policy=noeviction 设置为volatile-ttl(删除具有最近到期时间的密钥)。

这是做什么的,每当写命令发现你超过maxmemory,它会尝试根据策略为新密钥释放空间。 volatile-ttl 策略将首先驱逐任何剩余的过期密钥。 See evict.c.

您还可以增加后台任务的频率,以更频繁地清除过期密钥,请参阅redis.conf 中的 hz。你可以加倍到 20。

默认情况下,“hz”设置为 10。提高该值将使用更多 CPU 时 Redis 处于空闲状态,但同时会使 Redis 的响应速度更快 有很多key同时过期,可能会超时 处理更精确。

另外,activedefrag = yes 可能会有所帮助,请参阅 here

有一个新的active-expire-effortredis.conf 设置可以让你在 active-expire 中投入更多的 CPU,但它在最新的稳定版本 (5.0.7) 中不可用。

使用INFO memory 了解您的redis 服务器内存状态。如果以上内容对您没有帮助,请使用此输出更新问题。

【讨论】:

  • 将 maxmemory 值和 maxmemory-policy 设置为 volatile-ttl 将允许在达到 maxmemory 的情况下写入吗?它会只驱逐过期的密钥,还是我们会在达到 maxmemory 值时利用 Redis 驱逐未过期的密钥?将赫兹值加倍似乎是一个聪明的主意。我可能会从这个开始,看看 Redis 是否可以在填满密钥之前赶上过期的密钥。
  • 是的,volatile-ttl 将在达到maxmemory 的情况下允许写入,将易失性密钥(具有过期设置的密钥)从第一个过期(第一个过期)驱逐到最后一个过期。所以是的,如果没有已经过期的密钥,它将驱逐尚未过期的密钥。我也会从 hz 开始,不错的选择。但是设置 maxmemory 是最佳实践,如果您的操作系统启用了虚拟内存,您不想让 redis 占用所有系统内存,甚至不希望将内存分页(换出)到磁盘。
  • 谢谢,为 hz 参数设置一个更高的值解决了这个问题。加倍有帮助,但我可能必须将其设置为 30 或 40 以防止过期时间填满内存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 2012-02-15
  • 1970-01-01
相关资源
最近更新 更多