Redis 内存回收

本文涉及的产品
云数据库 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
相关文章
|
5天前
|
存储 缓存 NoSQL
Redis入门到通关之Redis内存淘汰(内存过期)策略
Redis入门到通关之Redis内存淘汰(内存过期)策略
20 3
|
18天前
|
算法 安全 Java
内存分配与回收策略
内存分配与回收策略
21 0
内存分配与回收策略
|
21天前
|
NoSQL 安全 Redis
redis内存限制与淘汰策略
Redis内存管理包括限制和淘汰策略。`maxmemory`配置参数决定内存上限,无设置时64位系统默认不限制,可能导致系统资源耗尽,生产环境建议设定合理值。当内存满时,未设置淘汰策略会导致写入错误。Redis提供8种淘汰策略,如LRU(最近最少使用)和LFU(最不经常使用),以及随机或基于过期时间的删除。需根据数据重要性、访问频率和一致性选择合适策略。
282 0
|
27天前
|
存储 缓存 NoSQL
Redis 服务器指南:高性能内存数据库的完整使用指南
Redis 服务器指南:高性能内存数据库的完整使用指南
|
28天前
|
存储 缓存 NoSQL
Redis的内存淘汰策略是什么?
【4月更文挑战第2天】Redis内存淘汰策略在内存满时,通过删除旧数据为新数据腾空间。策略包括:volatile-lru/LFU(基于LRU/LFU算法淘汰有过期时间的键),volatile-random/ttl(随机/按TTL淘汰),allkeys-lru/LFU(所有键的LRU/LFU),allkeys-random(随机淘汰所有键),以及noeviction(不淘汰,返回错误)。选择策略要考虑访问模式、数据重要性和性能需求。
|
2月前
|
缓存 NoSQL Redis
在Python Web开发过程中:数据库与缓存,除了Redis是内存数据库以外,还有哪些原因使其运行速度快?
Redis在Python Web开发中快速的原因:内存存储、多样化数据结构(如字符串、哈希、列表等)简化数据模型,单线程处理提高效率,结合非阻塞I/O;RDB和AOF提供持久化保障;TCP+二进制协议减少网络开销;管道技术提升通信效率。这些设计使Redis能高效处理高并发请求。
19 3
|
2月前
|
NoSQL 应用服务中间件 Linux
Redis的内存回收机制
Redis的内存回收机制
25 2
|
2月前
|
SQL Java 关系型数据库
flink cdc 内存问题之不会回收如何解决
Flink CDC(Change Data Capture)是一个基于Apache Flink的实时数据变更捕获库,用于实现数据库的实时同步和变更流的处理;在本汇总中,我们组织了关于Flink CDC产品在实践中用户经常提出的问题及其解答,目的是辅助用户更好地理解和应用这一技术,优化实时数据处理流程。
|
3月前
|
存储 缓存 NoSQL
内存淘金术:Redis 内存满了怎么办?
内存淘金术:Redis 内存满了怎么办?
41 1
|
4月前
|
存储 JSON NoSQL
Redis 内存优化神技,小内存保存大数据
Redis 内存优化神技,小内存保存大数据
40 0