Redis 的数据过期了就会马上删除么?
码哥,当 key 达到过期时间,Redis 就会马上删除么?
先说结论,并不会立马删除,Redis 有两种删除过期数据的策略:
- 定期选取部分数据删除;
- 惰性删除;
该命令在 Redis 2.4 版本,过期时间并不是很精确,它可能在零到一秒之间。
从 Redis 2.6 开始,过期错误为 0 到 1 毫秒。
EXPIRE key seconds [ NX | XX | GT | LT] 指令可以将指定的 key 设置过期时间,如果没有设置过期时间, key 将一直存在,除非我们明确将其删除,比如执行 DEL 指令。
所谓”狡兔死,走狗烹“,没用了就干掉,跟 35 岁就“毕业”是一个道理。
好慌……
从 Redis 版本 7.0.0 开始:EXPIRE 添加了选项:NX、XX和GT、LT 选项。
- NX:当 key 没有过期时才设置过期时间;
- XX:只有 key 已过期的时候才设置过期时间;
- GT:仅当新的到期时间大于当前到期时间时才设置过期时间;
- LT:仅在新到期时间小于当前到期时间才设置到过期时间。
过期与持久化
主从或者集群架构中,两台机器的时钟严重不同步,会有什么问题么?
key 过期信息是用 Unix 绝对时间戳表示的。
为了让过期操作正常运行,机器之间的时间必须保证稳定同步,否则就会出现过期时间不准的情况。
比如两台时钟严重不同步的机器发生 RDB 传输, slave 的时间设置为未来的 2000 秒,假如在 master 的一个 key 设置 1000 秒存活,当 Slave 加载 RDB 的时候 key 就会认为该 key 过期(因为 slave 机器时间设置为未来的 2000 s),并不会等待 1000 s 才过期。

惰性删除
惰性删除很简单,就是当有客户端的请求查询该 key 的时候,检查下 key 是否过期,如果过期,则删除该 key。
比如当 Redis 收到客户端的GET movie:小泽#玛……利亚.rmvb 请求,就会先检查 key = movie:小泽#玛……利亚.rmvb 是否已经过期,如果过期那就删除。
删除过期数据的主动权交给了每次访问请求。
该实现通过 expireIfNeeded函数实现,源码路径:src/db.c。
int expireIfNeeded(redisDb *db, robj *key, int force_delete_expired) {
// key 没有过期,return 0
if (!keyIsExpired(db,key)) return 0;
if (server.masterhost != NULL) {
if (server.current_client == server.master) return 0;
if (!force_delete_expired) return 1;
}
if (checkClientPauseTimeoutAndReturnIfPaused()) return 1;
/* Delete the key */
deleteExpiredKeyAndPropagate(db,key);
return 1;
}
定期删除
仅仅靠客户端访问来判断 key 是否过期才执行删除肯定不够,因为有的 key 过期了,但未来再也没人访问,这些数据要怎么删除呢?
不能让这些数据「占着茅坑不拉屎」。
所谓定期删除,也就是 Redis 默认每 1 秒运行 10 次(每 100 ms 执行一次),每次随机抽取一些设置了过期时间的 key,检查是否过期,如果发现过期了就直接删除。
注意:并不是一次运行就检查所有的库,所有的键,而是随机检查一定数量的键。
具体步骤如下:

- 从所有设置了过期时间的 key 集合中随机选择 20 个 key;
- 删除「步骤 1」发现的所有过期 key 数据;
- 「步骤 2 」结束,过期的 key 超过 25%,则继续执行「步骤 1」。
删除的源码 expire.c 的 activeExpireCycle 函数实现。
这也就意味着在任何时候,过期 key 的最大数量等于每秒最大写入操作量除以 4。
为啥不检查所有设置过期时间的 key?
你想呀,假设 Redis 里存放了 100 w 个 key,都设置了过期时间,每隔 100 毫秒就检查 100 w 个 key,CPU 全浪费在检查过期 key 上了,Redis 也就废了。
注意了:不管是定时删除,还是惰性删除。当数据删除后,master 会生成删除的指令记录到 AOF 和 slave 节点。
码哥,如果过期的数据太多,定时删除无法删除完全(每次删除完过期的 key 还是超过 25%),同时这些 key 也再也不会被客户端请求,也就是无法走惰性删除,会怎样?
会不会导致 Redis 内存耗尽,怎么破?
这个问题问得好,答案是走内存淘汰机制。
今天就到这里,说太多的话,大家容易在知识的海量里呛死,保命要紧,至于内存淘汰机制详情,请看下回分解。
参考资料
Redis 的数据过期了就会马上删除么?的更多相关文章
- 关于Redis数据过期策略
1.Redis中key的的过期时间 通过EXPIRE key seconds命令来设置数据的过期时间.返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间.在key上设置了过期时间后ke ...
- redis数据过期策略【转】
key的过期时间通常,Redis key被创建时不会自动关联过期时间,key将长久存在,除非通过DEL等命令显示的删除.EXPIRE命令簇可以为指定的key关联一个过期时间,代价是一点额外的内存开销. ...
- Redis数据过期策略
1.Redis中key的的过期时间 通过EXPIRE key seconds命令来设置数据的过期时间.返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间.在key上设置了过期时间后ke ...
- Redis数据过期和淘汰策略详解(转)
原文地址:https://yq.aliyun.com/articles/257459# 背景 Redis作为一个高性能的内存NoSQL数据库,其容量受到最大内存限制的限制. 用户在使用Redis时,除 ...
- Redis数据过期策略详解
http://www.cnblogs.com/xuliangxing/p/7151812.html 本文对Redis的过期机制简单的讲解一下 讲解之前我们先抛出一个问题,我们知道很多时候服务器经常会用 ...
- Redis学习笔记--Redis数据过期策略详解
本文对Redis的过期机制简单的讲解一下 讲解之前我们先抛出一个问题,我们知道很多时候服务器经常会用到redis作为缓存,有很多数据都是临时缓存一下,可能用过之后很久都不会再用到了(比如暂存sessi ...
- Redis学习笔记--Redis数据过期策略详解==转
本文对Redis的过期机制简单的讲解一下 讲解之前我们先抛出一个问题,我们知道很多时候服务器经常会用到redis作为缓存,有很多数据都是临时缓存一下,可能用过之后很久都不会再用到了(比如暂存sessi ...
- Redis(二十):Redis数据过期和淘汰策略详解(转)
原文地址:https://yq.aliyun.com/articles/257459# 背景 Redis作为一个高性能的内存NoSQL数据库,其容量受到最大内存限制的限制. 用户在使用Redis时,除 ...
- NoSql数据库Redis系列(6)——Redis数据过期策略详解
本文对Redis的过期机制简单的讲解一下 讲解之前我们先抛出一个问题,我们知道很多时候服务器经常会用到redis作为缓存,有很多数据都是临时缓存一下,可能用过之后很久都不会再用到了(比如暂存sessi ...
随机推荐
- 集合流之"交集(相同)和差集(区别的)"的使用
一.需求 今天做的是将两个字符串转为数组后再转集合,然后利用集合的流stream来进行差集过滤 二.差集代码 差集:将两个集合相同的数据去掉,留下不同的数据 1 @Test 2 public void ...
- 使用Ansible部署openstack平台
使用Ansible部署openstack平台 本周没啥博客水了,就放个云计算的作业上来吧(偷个懒) 案例描述 1.了解高可用OpenStack平台架构 2.了解Ansible部署工具的使用 3.使用A ...
- (5) 图和表(Figure and Table) 【论文写作】
- 罗振宇2022"时间的朋友"跨年演讲
罗振宇2022"时间的朋友"跨年演讲 行就行,不行我再想想办法. 原来,还能这么干! 堆资源不是解决问题的唯一道路,还是那句话:"处于困境中的人往往只关注自己的问题.而解 ...
- css预编译--sass进阶篇
基础篇中主要介绍了一些sass的基本特性,进阶篇中,主要是写一些我们常用的sass控制命令,函数和规则. 控制命令 可能看过基础篇的朋友会发现在有些代码中出现@if @else @each等,熟悉JS ...
- 饿了么组件库element-ui正则表达式验证表单,后端验证表单。
前言 老是遇到一些朋友问一些element-ui组件使用相关的基础问题,因为官方文档上并没有提供所有琐碎的功能代码demo.从这里开始我会根据我实际遇到的问题记录一些常见的官方文档没有详述的功能代码, ...
- python-转换函数使用
输入一个整数和进制,转换成十进制输出 输入格式: 在一行输入整数和进制 输出格式: 在一行十进制输出结果 输入样例: 在这里给出一组输入.例如: 45,8 输出样例: 在这里给出相应的输出.例如: 3 ...
- Java/C++实现装饰模式---模拟手机功能的升级过程
用装饰模式模拟手机功能的升级过程:简单的手机(SimplePhone)在接收来电时,会发出声音提醒主人:而JarPhone除了声音还能振动:更高级的手机(ComplexPhone)除了声音.振动外,还 ...
- 浅谈ES6中的Async函数
转载地址:https://www.cnblogs.com/sghy/p/7987640.html 定义:Async函数是一个异步操作函数,本质上,Async函数是Generator函数的语法糖.asy ...
- 【java】密码检查
[问题描述] 开发一个密码检查软件,密码要求: 长度超过8位 包括大小写字母.数字.其它符号,以上四种至少三种 不能有相同长度超2的子串重复 [输入形式] 一组或多组长度超过2的子符串.每组占一行 [ ...