最新消息:

Redis过期Key、内存回收的一些细节

IT技术 ipcpu 197浏览 0评论

Redis可以说是一个内存级数据库,受限于物理内存的大小,我们会限制Redis对内存的使用,这在Redis中主要体现在以下两个方面:

删除已经过期的Key
内存使用达到maxmemory上限时触发内存溢出控制策略

一、删除已经过期的Key

redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定时遍历这个字典来删除到期的 key。除了定时遍历之外,它还会使用惰性策略来删除过期的 key,定时删除是集中处理,惰性删除是零散处理。

惰性删除

所谓惰性策略就是在客户端访问这个 key 的时候,redis 对 key 的过期时间进行检查,如果过期了就立即删除。这种策略是出于节省CPU成本考虑,不需要单独维护TTL链表来处理过期键的删除。但是单独用这种方式存在内存泄露的问题,当过期键一直没有访问将无法得到及时删除,从而导致内存不能及时释放。正因为如此,Redis还提供另一种定时任务删除机制作为惰性删除的补充。

定期删除

Redis 默认会每秒进行十次过期扫描(通过配置参数hz控制),这种扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略。

1、从过期字典中随机挑选 20 个 key;
2、删除这 20 个 key 中已经过期的 key;
3、如果过期的 key 比率超过 1/4,那就重复步骤 1;

内存过期策略-执行流程2.png
同时,为了保证过期扫描不会出现循环过度,导致线程卡死现象,算法还增加了扫描时间的上限,默认不会超过 25ms。如果需要删除的Key数量很多,执行时间超过25ms咋办? Redis会采用快模式运行,快模式删除逻辑与慢模式相同,只是执行的超时时间不同。快模式超时时间为1毫秒且2秒内只能运行1次。设置快模式的目的也是为了尽快将过期Key清理。(默认会以慢模式运行,若是运行时间超过25ms才会启动快模式运行)

设想一个大型的 Redis 实例中所有的 key 在同一时间过期了,会出现怎样的结果?
毫无疑问,Redis 会持续扫描过期字典 (循环多次),直到过期字典中过期的 key 变得稀疏,才会停止 (循环次数明显下降)。这就会导致线上读写请求出现明显的卡顿现象。导致这种卡顿的另外一种原因是内存管理器需要频繁回收内存页,这也会产生一定的 CPU 消耗。所以我们可以在设置Key的过期时间时可以加上随机的时间差,以避免此类事情的发生。

redis.expire_at(key, random.randint(86400) + expire_ts)

从库的过期策略

从库不会进行过期扫描,从库对过期的处理是被动的。主库在 key 到期时,会在 AOF文件里增加一条 del 指令,同步到所有的从库,从库通过执行这条 del 指令来删除过期的key。
因为指令同步是异步进行的,所以主库过期的 key 的 del 指令没有及时同步到从库的
话,会出现主从数据的不一致,主库没有的数据在从库里还存在,比如集群环境分布式锁的算法漏洞就是因为这个同步延迟产生的。

二、内存溢出控制策略

当Redis所用内存达到maxmemory上限时(used_memory > maxmemory)会触发相应的溢出控制策略。具体策略受maxmemory-policy参数控制,Redis支持6种策略,如下所示:

1)noeviction:默认策略,不会删除任何数据,拒绝所有写入操作并返回客户端错误信息(error)OOM command not allowed when used memory,此时Redis只响应读操作。
2)volatile-lru:根据LRU算法删除设置了超时属性(expire)的键,直到腾出足够空间为止。如果没有可删除的键对象,回退到noeviction策略。
3)allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出足够空间为止。
4)allkeys-random:随机删除所有键,直到腾出足够空间为止。
5)volatile-random:随机删除过期键,直到腾出足够空间为止。
6)volatile-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果没有,回退到noeviction策略。


频繁执行回收内存成本很高,主要包括查找可回收键和删除键的开销,因此想要低响应延迟的场景,应该尽量避免内存溢出。

三、过期Key和被逐出Key的监控

内存溢出后,可以通过rate(redis_evicted_keys_total[5m]) 来监控被逐出Key的数量。
过期的Key,可以通过rate(redis_expired_keys_total[5m]) 来监控。

转载请注明:IPCPU-网络之路 » Redis过期Key、内存回收的一些细节

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址