Redis删除大量key后,占用的系统内存却没有释放?

我们首先来看看官方关于Redis内存管理的说明。

原文如下:https://redis.io/topics/memory-optimization#memory-allocation

Memory allocation

To store user keys, Redis allocates at most as much memory as the setting enables (however there are small extra allocations possible).maxmemory

The exact value can be set in the configuration file or set later via CONFIG SET (see Using memory as an LRU cache for more info). There are a few things that should be noted about how Redis manages memory:

Redis will not always free up (return) memory to the OS when keys are removed. This is not something special about Redis, but it is how most malloc() implementations work. For example if you fill an instance with 5GB worth of data, and then remove the equivalent of 2GB of data, the Resident Set Size (also known as the RSS, which is the number of memory pages consumed by the process) will probably still be around 5GB, even if Redis will claim that the user memory is around 3GB. This happens because the underlying allocator can't easily release the memory. For example often most of the removed keys were allocated in the same pages as the other keys that still exist.

The previous point means that you need to provision memory based on your peak memory usage. If your workload from time to time requires 10GB, even if most of the times 5GB could do, you need to provision for 10GB.However allocators are smart and are able to reuse free chunks of memory, so after you freed 2GB of your 5GB data set, when you start adding more keys again, you'll see the RSS (Resident Set Size) stay steady and not grow more, as you add up to 2GB of additional keys. The allocator is basically trying to reuse the 2GB of memory previously (logically) freed.Because of all this, the fragmentation ratio is not reliable when you had a memory usage that at peak is much larger than the currently used memory. The fragmentation is calculated as the physical memory actually used (the RSS value) divided by the amount of memory currently in use (as the sum of all the allocations performed by Redis). Because the RSS reflects the peak memory, when the (virtually) used memory is low since a lot of keys / values were freed, but the RSS is high, the ratio will be very high.RSS / mem_used If is not set Redis will keep allocating memory as it finds fit and thus it can (gradually) eat up all your free memory. Therefore it is generally advisable to configure some limit. You may also want to set to (which is not the default value in some older versions of Redis).maxmemorymaxmemory-policynoeviction.It makes Redis return an out of memory error for write commands if and when it reaches the limit - which in turn may result in errors in the application but will not render the whole machine dead because of memory starvation.

翻译如下:

 

内存分配

为了存储用户密钥,Redis最多分配设置允许的内存(但是也有少量的额外分配),确切的值可以在配置文件中设置,也可以在以后通过配置集进行设置(有关更多信息,请参阅将内存用作LRU缓存)。

关于Redis如何管理内存,需要注意以下几点:当密钥被移除时,Redis并不总是将内存释放(返回)给操作系统。这并不是Redis的独特之处,它是大多数malloc()实现的工作方式。例如,如果您用5GB的数据填充一个实例,然后删除相当于2GB的数据,则驻留集大小(Resident Set Size)(也称为RSS,即进程消耗的内存页数)可能仍将在5GB左右,即使Redis会声称用户内存约为3GB。发生这种情况是因为底层分配器无法轻松释放内存。例如,通常大多数被移除的键与仍然存在的其他键分配在同一页中。前一点意味着您需要根据峰值内存使用情况来配置内存。如果您的工作负载不时需要10GB,即使大多数情况下5GB都可以,您也需要为10GB进行调配。不过,分配器是智能的,能够重用空闲内存块,因此,当您释放了2GB的5GB数据集后,当您再次开始添加更多密钥时,您将看到RSS(驻留集大小)保持稳定,而不会增加,因为您添加了2GB的额外密钥。分配器基本上是在尝试重用先前(逻辑上)释放的2GB内存。

正因为如此,当内存使用率峰值远大于当前使用的内存时,碎片率是不可靠的。碎片计算为实际使用的物理内存(RSS值)除以当前使用的内存量(作为Redis执行的所有分配的总和)。因为RSS反映了峰值内存,当(实际上)使用的内存很低,因为释放了很多键/值,但是RSS很高,那么这个比率会非常高。如果RSS/mem_used没有设置,Redis将继续分配它认为合适的内存,因此它可以(逐渐)吃掉你所有的空闲内存。因此,通常建议配置一些限制。您可能还需要设置为(这不是某些旧版本的Redis的默认值)

它使Redis在达到限制时返回write命令的内存不足错误-这反过来可能导致应用程序出错,但不会因为内存不足而导致整个机器死机。

综上所述(官方说明),我们不用再担心这个问题了。其实这样也有个好处,就是如果再有key写入,则无需再去申请系统内存,来减少内存申请操作。如果非要把这些Redis空闲空间返还操作系统可以执行命令MEMORY PURGE来进行空间整理,或者开启activedefrag,进行热碎片整理(该操作在主线程执行,会占用CPU,可以设置CPU占用率)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值