Redis 内存回收

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 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:达到最大内存,增加数据,报错
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
12天前
|
程序员 开发者
分代回收和手动内存管理相比有何优势
分代回收和手动内存管理相比有何优势
|
1月前
|
算法 Java 程序员
内存回收
【10月更文挑战第9天】
43 5
|
1月前
|
存储 缓存 NoSQL
Redis Quicklist 竟让内存占用狂降50%?
【10月更文挑战第11天】
41 2
|
1月前
|
Java 测试技术 Android开发
让星星⭐月亮告诉你,强软弱虚引用类型对象在内存足够和内存不足的情况下,面对System.gc()时,被回收情况如何?
本文介绍了Java中四种引用类型(强引用、软引用、弱引用、虚引用)的特点及行为,并通过示例代码展示了在内存充足和不足情况下这些引用类型的不同表现。文中提供了详细的测试方法和步骤,帮助理解不同引用类型在垃圾回收机制中的作用。测试环境为Eclipse + JDK1.8,需配置JVM运行参数以限制内存使用。
32 2
|
2月前
|
缓存 监控 NoSQL
阿里面试让聊一聊Redis 的内存淘汰(驱逐)策略
大家好,我是 V 哥。粉丝小 A 面试阿里时被问到 Redis 的内存淘汰策略问题,特此整理了一份详细笔记供参考。Redis 的内存淘汰策略决定了在内存达到上限时如何移除数据。希望这份笔记对你有所帮助!欢迎关注“威哥爱编程”,一起学习与成长。
|
2月前
|
存储 Prometheus NoSQL
Redis 内存突增时,如何定量分析其内存使用情况
【9月更文挑战第21天】当Redis内存突增时,可采用多种方法分析内存使用情况:1)使用`INFO memory`命令查看详细内存信息;2)借助`redis-cli --bigkeys`和RMA工具定位大键;3)利用Prometheus和Grafana监控内存变化;4)优化数据类型和存储结构;5)检查并调整内存碎片率。通过这些方法,可有效定位并解决内存问题,保障Redis稳定运行。
|
1月前
|
算法 Java
JVM进阶调优系列(3)堆内存的对象什么时候被回收?
堆对象的生命周期是咋样的?什么时候被回收,回收前又如何流转?具体又是被如何回收?今天重点讲对象GC,看完这篇就全都明白了。
|
2月前
|
缓存 NoSQL 算法
14)Redis 在内存用完时会怎么办?如何处理已过期的数据?
14)Redis 在内存用完时会怎么办?如何处理已过期的数据?
56 0
|
2月前
|
存储 缓存 NoSQL
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
71 0
|
2月前
|
数据安全/隐私保护 虚拟化
基于DAMON的内存能回收 【ChatGPT】
基于DAMON的内存能回收 【ChatGPT】