码哥,当 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 添加了选项:NXXXGTLT 选项。

  • 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,检查是否过期,如果发现过期了就直接删除。

注意:并不是一次运行就检查所有的库,所有的键,而是随机检查一定数量的键。

具体步骤如下:

  1. 从所有设置了过期时间的 key 集合中随机选择 20 个 key
  2. 删除「步骤 1」发现的所有过期 key 数据;
  3. 「步骤 2 」结束,过期的 key 超过 25%,则继续执行「步骤 1」。

删除的源码 expire.c 的 activeExpireCycle 函数实现

这也就意味着在任何时候,过期 key 的最大数量等于每秒最大写入操作量除以 4。

为啥不检查所有设置过期时间的 key?

你想呀,假设 Redis 里存放了 100 w 个 key,都设置了过期时间,每隔 100 毫秒就检查 100 w 个 key,CPU 全浪费在检查过期 key 上了,Redis 也就废了。

注意了:不管是定时删除,还是惰性删除。当数据删除后master 会生成删除的指令记录到 AOFslave 节点

码哥,如果过期的数据太多,定时删除无法删除完全(每次删除完过期的 key 还是超过 25%),同时这些 key 也再也不会被客户端请求,也就是无法走惰性删除,会怎样?

会不会导致 Redis 内存耗尽,怎么破?

这个问题问得好,答案是走内存淘汰机制

今天就到这里,说太多的话,大家容易在知识的海量里呛死,保命要紧,至于内存淘汰机制详情,请看下回分解。

参考资料

Redis 的数据过期了就会马上删除么?的更多相关文章

  1. 关于Redis数据过期策略

    1.Redis中key的的过期时间 通过EXPIRE key seconds命令来设置数据的过期时间.返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间.在key上设置了过期时间后ke ...

  2. redis数据过期策略【转】

    key的过期时间通常,Redis key被创建时不会自动关联过期时间,key将长久存在,除非通过DEL等命令显示的删除.EXPIRE命令簇可以为指定的key关联一个过期时间,代价是一点额外的内存开销. ...

  3. Redis数据过期策略

    1.Redis中key的的过期时间 通过EXPIRE key seconds命令来设置数据的过期时间.返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间.在key上设置了过期时间后ke ...

  4. Redis数据过期和淘汰策略详解(转)

    原文地址:https://yq.aliyun.com/articles/257459# 背景 Redis作为一个高性能的内存NoSQL数据库,其容量受到最大内存限制的限制. 用户在使用Redis时,除 ...

  5. Redis数据过期策略详解

    http://www.cnblogs.com/xuliangxing/p/7151812.html 本文对Redis的过期机制简单的讲解一下 讲解之前我们先抛出一个问题,我们知道很多时候服务器经常会用 ...

  6. Redis学习笔记--Redis数据过期策略详解

    本文对Redis的过期机制简单的讲解一下 讲解之前我们先抛出一个问题,我们知道很多时候服务器经常会用到redis作为缓存,有很多数据都是临时缓存一下,可能用过之后很久都不会再用到了(比如暂存sessi ...

  7. Redis学习笔记--Redis数据过期策略详解==转

    本文对Redis的过期机制简单的讲解一下 讲解之前我们先抛出一个问题,我们知道很多时候服务器经常会用到redis作为缓存,有很多数据都是临时缓存一下,可能用过之后很久都不会再用到了(比如暂存sessi ...

  8. Redis(二十):Redis数据过期和淘汰策略详解(转)

    原文地址:https://yq.aliyun.com/articles/257459# 背景 Redis作为一个高性能的内存NoSQL数据库,其容量受到最大内存限制的限制. 用户在使用Redis时,除 ...

  9. NoSql数据库Redis系列(6)——Redis数据过期策略详解

    本文对Redis的过期机制简单的讲解一下 讲解之前我们先抛出一个问题,我们知道很多时候服务器经常会用到redis作为缓存,有很多数据都是临时缓存一下,可能用过之后很久都不会再用到了(比如暂存sessi ...

随机推荐

  1. 「腾讯视频」微信小程序插件介绍

    上期,我们在<从原理到应用,一文带你了解小程序插件能力>一文中介绍了小程序插件的意义.作用以及应用.今天开始,我们会每期与大家分享一款优秀的小程序插件,从使用场景到使用方法,都将作出详细的 ...

  2. 报错需要选择一个空目录,或者选择的非空目录下存在 app.json 或者 project.config.json解决方案

    前言 小程序的第一个坑就是,创建了一个小程序项目,却在微信web开发者工具无法打开... 报了个错:需要选择一个空目录,或者选择的非空目录下存在 app.json 或者 project.config. ...

  3. WPF控件大全(表格)-学习总结

    Label标签 label控件:一般用户描述性文字显示. 在Label控件使用时,一般给予用户提示.用法上没有什么很特殊的,label控件的值记住:不是Text 而是 Content属性. TextB ...

  4. pydev+eclipse写python代码

    首先,下载pydev:PyDev for Eclipse - Browse /pydev at SourceForge.net (建议下载到本地,之前看其他文章时,进行了如下安装: 启动 Eclips ...

  5. c++实现中介者模式--虚拟聊天室

    内容: 在"虚拟聊天室"实例中增加一个新的具体聊天室类和一个新的具体会员类,要求如下: 1. 新的具体聊天室中发送的图片大小不得超过20M. 2. 新的具体聊天室中发送的文字长度不 ...

  6. java重载时自动转换咋回事?举例说明

    当一个重载的方法被调用时,Java在调用方法的参数和方法的自变量之间寻找匹配.    但是,这种匹配并不总是精确的.只有在找不到精确匹配时,Java的自动转换才会起作用. (如果定义了test(int ...

  7. 判断H5页面是在小程序的webview环境中,还是在微信环境中,还是不在微信

    <script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js" type="text/javascrip ...

  8. Docker 核心知识回顾

    Docker 核心知识回顾 最近公司为了提高项目治理能力.提升开发效率,将之前的CICD项目扩展成devops进行项目管理.开发人员需要对自己的负责的项目进行流水线的部署,包括写Dockerfile ...

  9. QGIS 安装

    QGIS 安装 官网 https://www.qgis.org/ 下载地址 https://www.qgis.org/en/site/forusers/download.html 参考文档 https ...

  10. 序列化之Serializer类与ModelSerializer类的使用

    序列化之Serializer类的使用(5星) 作用: 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 反序列化,把客户端发送过来的数据,经过request以后变成字 ...