我有一个 Redis 3.0.5 实例,随着时间的推移,其 mem_fragmentation_ratio 往往会增长。
使用该实例的应用程序正在不断地创建和删除密钥。
一个月后,我的 mem_fragmentation_ratio 值大于 1.30。这会影响该服务器上 Redis 的内存占用:
~$ redis-cli info memory
# Memory
used_memory:7711297480
used_memory_human:7.18G
used_memory_rss:10695098368
used_memory_peak:11301744128
used_memory_peak_human:10.53G
used_memory_lua:95232
mem_fragmentation_ratio:1.39
mem_allocator:jemalloc-3.6.0
如果我重新启动 Redis 服务并从 AOF 重新加载,mem_fragmentation_ratio 将回到可接受的水平(1.06):
~$ redis-cli info memory
# Memory
used_memory:7493466968
used_memory_human:6.98G
used_memory_rss:7924920320
used_memory_peak:8279112992
used_memory_peak_human:7.71G
used_memory_lua:91136
mem_fragmentation_ratio:1.06
mem_allocator:jemalloc-3.6.0
回收 Redis 会对我们的应用程序产生影响(即使我们在从属服务器重启后使用 Sentinel 故障转移来执行此操作)。
还有其他方法可以减少 mem_fragmentation_ratio 吗,比如我可以安排非高峰期的“碎片整理”过程?
答案1
内存碎片是一个不小的问题。
在 v4 之前,解决该问题的唯一方法是重新启动进程(可能在创建从属进程、提升它并将流量重定向到它之后)。从 v4 开始,有一个实验性的主动内存碎片整理机制,可以通过简单的 启用CONFIG SET activedefrag yes
。
答案2
主动碎片整理(在 Redis 4 中引入)在 Redis 5 中得到了改进。引用 AWS 关于 Redis 5 的公告:
此版本附带了所谓的主动碎片整理 2:它更快、更智能、延迟更低。此功能对于分配器无法将碎片保持在足够低水平的工作负载特别有用,因此策略是 Redis 和分配器合作。要实现这一点,必须使用 Jemalloc 分配器。幸运的是,它是 Linux 上的默认分配器。
另一句引言来自Redis 主要开发人员:
主动碎片整理版本 2。对正在运行的服务器的内存进行碎片整理是一种黑魔法,但 Oran Agra 改进了他过去的努力,现在它比以前更好用。对于容易使 Jemalloc 碎片化的长期运行工作负载非常有用。
如果您正在使用 Jemalloc 分配器并且正在努力解决碎片问题,我建议您启用该功能:
CONFIG SET activedefrag yes
如果你来自 AWS 的 ElastiCache Redis,Jemalloc 是默认值,并且支持主动碎片整理。Runningmemory doctor
还建议在碎片级别过高时启用该功能。