Redis过期策略

一、Redis过期策略

redis通常被用来当作缓存 使用,虽然它也可以用作数据库 和消息队列,但是数据库方面,redis相较于Mysql,Hbase,Oracle等数据库又逊色了很多;消息队列方面,又没有RabbitMQ等消息队列功能更完善,程序员们肯定会选择更优秀的工具。

由于是缓存,那redis中存储的数据通常是不固定的,通常会给数据的键值对设置过期时间,从而能够适当地释放redis的存储空间,那么redis是如何设置过期时间的呢?

redis的过期策略是:惰性删除 + 定期删除

1.1 惰性删除

所谓惰性删除,字面意思就是redis很懒惰,当一个键值对达到过期时间后,不会立即删除,而是当下一次访问到该Key时,发现过期,再删除该键值对。

  • 当已过期,删除key,返回nil;
  • 当未过期,返回对应的value值;
  • 执行所有读写命令之前,先调用redis内部的expireIfNeed函数判断是否过期。

惰性删除的好处 是cpu消耗极少,只需要在访问过期的key值之后,再进行删除逻辑。

但其弊端 也很明显---易形成僵尸数据。就是如果不访问已过期的key值,就不管,任其存在于redis内存中占用资源空间,这就是僵尸数据。我们都知道redis作为缓存来说,其内存是很宝贵的,如果只使用惰性删除会导致内存空间不足的问题。

1.2 定期删除

所谓定期删除,是指redis会每隔100ms扫描设置了过期时间的键空间中以及过期的键值对,并删除过期的key。

假设redis中存储了10w+设置了过期时间的数据,每一次扫描所有的key来查找已过期的key,不到下一次扫描,redis就以及瘫痪掉了,因为数据量太大,如果每隔100ms就扫描所有的key,cpu全消耗在扫描key值上了。所以此处说的定期扫描,是每隔100ms对键空间中的部分数据进行扫描 ,而不是全部。

redis综合使用惰性删除和定期删除,就能够解决大部分已过期数据的删除,因为显然,定期删除部分过期数据和当访问才删除不一定能清理掉所有的过期数据。那随着存储的数据越来越多,redis存储内存肯定会在某一刻被填满,此时该怎样释放空间呢?

答案是:内存淘汰机制。

二、内存淘汰机制

内存淘汰机制,实际上是redis过期策略的兜底策略,由于惰性删除和定期删除会残留部分key,当redis占用内存达到最大值,就会触发内存淘汰机制,主要策略有以下几种:

  • noeviction :当内存占满,有新的数据需要写入时,直接报错拒绝。(默认策略,最不推荐)
  • allkeys-lru:在全部key中,删除最近最少使用的key。(使用频率最高)
  • allkeys-lfu:在全部key中,删除使用频率最低的key。
  • allkeys-random:在全部key中,随机删除。
  • volatile-lru:在过期key中,删除最近最少使用的key。
  • volitaile-lfu:在全部key中,删除使用频率最低的key。
  • volitaile-random:在过期key中,随机删除。
  • volatile-ttl:在过期key中,优先删除存货时间最短的。

三、完整工作流程总结

  1. 使用 SET key value EX seconds 给key设置过期时间;
  2. key过期时间到了,但不会立即删除;
  3. 当用户访问key时,删除key;
  4. redis每隔100ms对部分过期的key进行删除;
  5. 当redis存储内存被占满,触发内存淘汰机制。

本片文章讨论了关于redis过期策略的知识,希望可以对大家学习redis有所帮助,如有表述错误,希望指点。

相关推荐
Fatbobman(东坡肘子)19 小时前
快速消失的硬盘容量 -- 肘子的 Swift 周报 #160
开发语言·人工智能·redis·ios·swiftui·iphone·swift
温暖小土20 小时前
在 CentOS 上安装 Redis Stack
linux·redis·centos
Mikko71 天前
Redis 连接数满了服务端有错误信息吗?连接数不增加却命令超时?6.2 实测连接池、超时与大 key 怎么判定
java·spring boot·redis·后端
无言听风雨丶1 天前
Redis 运维实战与排错
运维·数据库·redis
字节探索1 天前
Redis 分布式锁:从 SETNX 误删到看门狗自动续期的原理与实践
redis·分布式
真上帝的左手1 天前
30. 技术专题-‌应用框架组件-缓存-Redis
数据库·redis·分布式·缓存·中间件
bksczm1 天前
C++Redis开发(Ubuntu 22.04)
数据库·redis·缓存
goehou1 天前
缓存该删还是该改,LLM 服务里的双写问题
redis·缓存·llm·一致性·系统设计
余槐i1 天前
Spring Boot 3.2 偶发500无日志:线程池复用导致请求上下文丢失
spring boot·redis·后端·mysql·性能优化
IT规划师1 天前
Redis 数据类型全解 - ZSet:两个编码,七种玩法(五)
redis·.net