【问题标题】:How to determine Redis memory leak?如何判断 Redis 内存泄漏?
【发布时间】:2014-08-09 20:24:49
【问题描述】:

从昨天开始,我们的 redis 服务器逐渐(200MB/小时)使用更多内存,而键的数量(330K)及其数据量(132MB redis-rdb-tools)基本保持不变。

redis-cli info 的输出显示 6.89G 已用内存?!

redis_version:2.4.10
redis_git_sha1:00000000
redis_git_dirty:0
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.6
process_id:3437
uptime_in_seconds:296453
uptime_in_days:3
lru_clock:1905188
used_cpu_sys:8605.03
used_cpu_user:1480.46
used_cpu_sys_children:1035.93
used_cpu_user_children:3504.93
connected_clients:404
connected_slaves:0
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
used_memory:7400076728
used_memory_human:6.89G
used_memory_rss:7186984960
used_memory_peak:7427443856
used_memory_peak_human:6.92G
mem_fragmentation_ratio:0.97
mem_allocator:jemalloc-2.2.5
loading:0
aof_enabled:0
changes_since_last_save:1672
bgsave_in_progress:0
last_save_time:1403172198
bgrewriteaof_in_progress:0
total_connections_received:3616
total_commands_processed:127741023
expired_keys:0
evicted_keys:0
keyspace_hits:18817574
keyspace_misses:8285349
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:1619791
vm_enabled:0
role:slave
master_host:***BLOCKED***
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
db0:keys=372995,expires=372995
db6:keys=68399,expires=68399

当我们将 (.net) 客户端代码从 BookSleeve 1.1.0.4 更新到 ServiceStack v3.9.71 以准备升级到 Redis 2.8 时,问题就开始了。但是很多其他的东西都更新到了而且我们的会话状态存储(也是redis,但带有harbor客户端)没有表现出相同的症状。

所有 Redis 内存都去哪儿了?如何解决它的使用问题?

编辑:我刚刚重启了这个实例,内存恢复到 350M,现在又开始爬升了。前 10 个最大对象的大小仍然相同,从 100K 到 nr 1 的 25M 不等。键的数量已降至 270K(之前为 330K)。

【问题讨论】:

  • 是否有下游副本?是否有意外数量的密钥:是否可能没有告知内容过期?
  • 下游副本是什么意思?总共有 8 台服务器,一个 master 有两个 master/slave,每个 master/slave 有两个 slave。
  • 内存使用异常的一个潜在原因是从服务器损坏,即内存较高的服务器的从服务器工作不正常,正在备份工作
  • 我已经使用 redis-rdb-tools 查看了这些密钥,但没有显示任何异常。奇怪的是,存储在键中的所有数据的总和只是 redis 使用的数据的一小部分。重新启动时,它会与 master 重新同步,并从大约 315M 开始。
  • 好了,如何识别坏掉的slave?

标签: memory-leaks redis stackexchange.redis


【解决方案1】:

以下是 Redis 中“隐藏”内存消耗的一些来源:

  • Marc 已经提到了由 master 维护的缓冲区来为 slave 提供数据。如果从属落后于其主控(例如,因为它在较慢的机器上运行),那么主控将消耗一些内存。

  • 当检测到长时间运行的命令时,Redis 会将它们记录在 SLOWLOG 区域中,这会占用一些内存。您可能需要使用 SLOWLOG LEN 命令来检查此处的记录数。

  • 通信缓冲区也可以占用内存。据我记得,对于旧版本的 Redis(而且 2.4 已经很老了——你应该真的升级),它是无限的,这意味着如果你在某个点传输一个大对象,与这个客户端连接相关的通信缓冲区将会增长并且永不收缩。如果有很多客户偶尔处理大型对象,这可能是一种可能的解释。如果您使用命令从 Redis 检索非常大的数据(一次性),它也可以作为一种解释。例如,在存储数百万个密钥的 Redis 服务器上应用一个简单的 KEYS * 命令将消耗大量内存。

您提到您有 25 MB 大的对象。您有 404 个客户端连接,如果每个连接都需要在某个时间点访问此类对象,则会消耗 10 GB 的内存。

【讨论】:

  • 有趣的信息。我们已经升级到 Redis 2.8。在下结论之前必须进行监控。其他问题(100% CPU)仍然出现。明天我会运行你提到的第一件事。
  • SLOWLOG 确实显示了 70 多个条目并且还在增加。我正在答案中提到的另一个线程中继续这项调查。 Redis 2.8 解决了内存问题。
  • ServiceStack V3 和 Redis 2.4 之间似乎存在问题。内存现在稳定在 220M 左右,峰值负载时为 500M。我们仍然遇到性能问题,但我正在另一个线程中继续调查:How to increase Redis performance when 100% CPU? Sharding? Fastest .Net Client?
猜你喜欢
  • 1970-01-01
  • 2011-11-15
  • 2022-11-22
  • 2012-09-14
  • 2012-03-07
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
相关资源
最近更新 更多