Redis删除(del)key后内存无法释放的原因和解决方案

现象

项目中,redis的 key value 量太多,决定对某个db下的key进行删除,也就是Del key。
在删除前,通过info memory看下内存情况

Memory
used_memory:2205816296
used_memory_human:4.8G
used_memory_rss:5579214848
used_memory_rss_human:5.70G
...
...

通过一个小程序,一直删除可丢弃的key。
1小时后,过来一看:

Memory
used_memory:2205816296
used_memory_human:2.05G
used_memory_rss:5579214848
used_memory_rss_human:5.70G
...
...

发现redis内部的used_memory使用量已经下降到2.05G了,但是used_memory_rss(redis在系统中进程占用的内存量)并未降低。

原因

官方已经说了具体原因
https://redis.io/topics/memory-optimization
概括了点内容:

当键被删除时,Redis并不总是释放(返回)内存到操作系统。这并不是Redis的特别之处,但大多数malloc()实现都是这样工作的。

例如一个实例有5gb的数据,然后删除相当于2gb的数据,used_memory_rss可能仍会5 gb左右。这是因为底层分配器不能轻松地释放内存。例如,通常将删除的大多数键分配到与其他仍然存在的键相同的页面中。

然而分配器是聪明和能够重用空闲块的内存,所以在你释放2 gb的5 gb的数据集,当你开始再次增加键,您将看到used_memory_rss保持稳定而不会再增加很多。分配器基本上是尝试重用以前(逻辑上)释放的2GB内存。

解决方案

通过原因可以知道,我们其实不用去关注。
特别是我们定义了maxmemory后,并且定义了maxmemory_policy,那么即使内存满了,redis也会按照淘汰机制方案,清除一些不需要的key,来存放新的key。

但是如果已经影响到系统内存使用了,也有下面三种方案:

  1. 可以通过 MEMORY PURGE命令进行内存整理。(瞬时,能稍微腾出rss内存空间)
  2. 开启activedefrag,热碎片整理。(会占用CPU,在主线程执行,可以设置CPU占用率)
  3. 重启。

你可能感兴趣的:(其他,redis,内存释放,del,key)