redis-内存回收

129 阅读2分钟

摘要

众所周知,redis的性能强,最主要的原因是基于内存存储,但是内存资源是有限且宝贵的,除了我们手动设置内存存储上限和过期时间,但存储的数据达到一定的量的时候,redis会按照内存淘汰策略进行淘汰数据。本文针对过期key的回收和redis提供的内存淘汰策略进行详细的探讨。

过期key的处理

在redis的数据库中存在两张dict表,一张用来存储key,value数据,一张用于存储key对应的过期时间。

清理过期key存在两种策略。redis会同时使用这两种策略

一、惰性删除:

当客户端在访问某一个key时,redis会检查存储key对应过期时间的表,如果该key已经过期,则进行删除。也就是说,如果没有访问一个过期的key,它仍然存储在database中。

  • 优点:CPU友好
  • 缺点:内存不友好,过期key仍有可能占用 内存

二、周期性删除:

通过设置一个定时任务,周期性的抽取部分key进行检查,如果过期则进行删除。

执行的周期也分SLOWFAST模式。

SLOW模式:按照server.hz的频率来执行过期key的清理,每秒执行server.hz次,默认情况下server.hz为10。并且每次清理过程不超过25ms。

FAST模式:在每个事件循环前会调用beforeSleep()函数,执行过期key清理。

redis内存淘汰策略

当redis使用的内容达到上限时,redis会主动清理一下key以释放内存。

Redis支持8种不同策略来选择要删除的key:

  • 全体key
    • 随机淘汰 allkeys-random
    • 基于LRU进行淘汰 allkeys-lru
    • 基于LFU进行淘汰 allkeys-lfu
    • 不淘汰,拒绝写入新数据(默认策略) no-eviction
  • 设置了TTL的key
    • 随机淘汰 volatile-random
    • 基于LRU进行淘汰 volatile-lru
    • 基于LFU进行淘汰 volatile-lfu
    • 优先淘汰TTL小的key volatile-ttl

补充:

  • LRU(Least Recently Used),最少最近使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
  • LFU(Least Frequently Used),最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高。