Redis 内存回收


在 RedisDB 利用两个 dict 分别来记录 key-value 和 key-TTL。

在这里插入图片描述
对应的源码:

typedef struct redisDb {
    dict *dict;        // 存放 key-value,也被称为 keyspace
    dict *expires;     // 存放 key-TTL
    dict *blocking_keys;  /* Keys with clients waiting for data (BLPOP)*/
    dict *ready_keys;     /* Blocked keys that received a PUSH */
    dict *watched_keys;   /* WATCHED keys for MULTI/EXEC CAS */
    int id;               /* Database ID, 0~15 */   
    long long avg_ttl;    // 记录平均 TTL 时长
    unsigned long expires_cursor; // expire 检查时在 dict 中抽样的索引位置 
    list *defrag_later;         // 等待碎片整理的 key 列表
} redisDb;

1、过期删除

当一个 key 设置过期时间时,Reids 会把 key 和过期时间 ttl 存储到过期字典expires中.

设置 key 的过期时间的命令

# 设置 key 的过期时间
expire key seconds
pexpire key milliseconds
# 查看 key 的过期时间
ttl key
pttl key
# 对象空转时长
object idletime key

当查询一个 key 时,Redis 首先检查该 key 是否存在于过期字典中

  • 若不在,正常读取键值对
  • 若存在,获取 key 的过期时间,然后与当前系统时间比较,若比当前系统时间小,则判断 key 已过期。

当 key 过期后,需要有相应的机制将已过期的键值对删除。

1.1、过期删除策略

惰性删除

不主动删除过期 key,每次访问 key 时,都检测 key 是否过期,若过期则删除 key。

惰性删除的特点

  • 优点:将检查 key 是否过期的操作分布在每一个命令操作时,占用很少的系统资源,对 cpu 时间友好
  • 缺点:未访问的过期 key 长时间保留在内存中不会释放,造成内存空间的浪费
定时删除

定期从数据库中随机抽取一定数量的 key 检查是否过期,并删除其中的过期 key

  • 从过期字典中随机抽取 20 个 key;
  • 检查这 20 个 key 是否过期,并删除已过期的 key;
  • 如果本轮检查的已过期 key 的数量,超过 5 个(20/4),也就是「已过期 key 的数量」占比「随机抽取 key 的数量」大于 25%,则继续重复步骤 1;如果已过期的 key 比例小于 25%,则停止继续删除过期 key,然后等待下一轮再检查。

同时为了保证定期删除不会出现循环过度,导致线程卡死现象。为此增加了定期删除循环流程的时间上限,默认不会超过 25ms。

定期删除的特点

  • 优点:通过限制删除操作执行的时长和频率,减少删除操作对 cpu 的影响,同时也能删除一部分过期数据,减少了过期 key 对空间的无效占用
  • 缺点:难以确定删除操作执行的时长和频率。执行频繁对 cpu 不友好,执行太少,无法及时释放过期 key 占用的内存。

2、内存淘汰

当 Redis 内存使用达到阈值 maxmemory 时,主动挑选部分 key 删除以释放更多的内存

配置 redis.config

 maxmemory 		  # 访问内存上限,通常设置最大内存的一半, 
 maxmemory-policy  # 内存淘汰策略

2.1、内存淘汰策略

过期 key 范围内淘汰

  • volatile-lru:最长时间没有使用
  • volatile-lfu:最少次数使用
  • volatile-ttl:最近要过期
  • volatile-radom:随机

淘汰所有 key 范围内淘汰

  • allkeys-lru
  • allkeys-lfu
  • allkeys-radom

禁止淘汰

  • no-evicition:达到最大内存,增加数据,报错
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值