Redis过期数据的删除策略
1 介绍
Redis 是一个kv型数据库,我们所有的数据都是存放在内存中的,但是内存是有大小限制的,不可能无限制的增量。
想要把不需要的数据清理掉,一种办法是直接删除,这个咱们前面章节有详细说过;另外一种就是设置过期时间,缓存过期后,由Redis系统自行删除。
这边需要注意的是,缓存过期之后,并不是马上删除的,那Redis是怎么删除过期数据的呢?主要通过两个方式
- 惰性删除
- 通过定时任务,定期选取部分数据删除
2 Redis缓存过期命令
我们通过以下指令给指定key的缓存设置过期时间,如果都没设置过期时间, key 将一直存在,直到我们使用 Del 的命令明确删除掉。
# 缓存时间过期命令,参考如下
EXPIRE key seconds [ NX | XX | GT | LT]
Redis 7.0 开始,EXPIRE 添加了 NX、XX和GT、LT 选项,分别代表如下:
- NX:仅当Key没有过期时设置过期时间
- XX:仅当Key已过期时设置过期时间
- GT:仅当新到期时间大于当前到期时间时设置到期时间
- LT:仅当新到期时间小于当前到期时间时设置到期时间
其中,GT、LT和NX选项是互斥的,下面是官方的测试用例:
redis> SET mykey "Hello"
"OK"
redis> EXPIRE mykey 10
(integer) 1
redis> TTL mykey
(integer) 10
redis> SET mykey "Hello World"
"OK"
redis> TTL mykey
(integer) -1
redis> EXPIRE mykey 10 XX
(integer) 0
redis> TTL mykey
(integer) -1
redis> EXPIRE mykey 10 NX
(integer) 1
redis> TTL mykey
(integer) 10
3 两种过期数据的删除方式
我们前面说过,Redis删除过期数据主要通过以下两个方式,我们一个个来看:
- 惰性删除
- 通过定时任务,定期选取部分数据删除
3.1 惰性删除
惰性删除比较简单,当客户端请求过来查询我们的key的时候,先对key做一下检查,如果没过期则返回缓存数据,如果过期,则删除缓存,重新从数据库中获取数据。
这样,我们就把删除过期数据的主动权交给了访问请求的客户端,如果客户端一直没请求,那这个过期缓存可能就长时间得不到释放。
Redis的源码 src/db.c 中的 expireIfNeeded 方法 就是实现以上惰性删除逻辑的,我们来看看:
int expireIfNeeded(redisDb *db, robj *key, int force_delete_expired) {// 对于未过期的key,直接 return 0if (!keyIsExpired(db,key)) return 0; /* If we are running in the context of a slave, instead of* evicting the expired key from the database, we return ASAP:* the slave key expiration is controlled by the master that will* send us synthesized DEL operations for expired keys.** Still we try to return the right information to the caller,* that is, 0 if we think the key should be still valid, 1 if* we think the key is expired at this time. */if (server.masterhost != NULL) {if (server.current_client == server.master) return 0;if (!force_delete_expired) return 1;}/* If clients are paused, we keep the current dataset constant,* but return to the client what we believe is the right state. Typically,* at the end of the pause we will properly expire the key OR we will* have failed over and the new primary will send us the expire. */if (checkClientPauseTimeoutAndReturnIfPaused()) return 1;/* Delete the key */deleteExpiredKeyAndPropagate(db,key);return 1;
}
3.2 定期删除
刚才前面说过了,仅靠客户端访问来对过期缓存执行删除远远不够,因为有的 key 过期了,但客户端一直没请求,那这个过期缓存可能就长时间甚至永远得不到释放。
所以除了惰性删除,Redis 还可以通过定时任务的方式来删除过期的数据。定时任务的发起的频率由redis.conf配置文件中的hz来进行配置
# 代表每1s 运行 10次
hz 10
Redis 默认每 1 秒运行 10 次,也就是每 100 ms 执行一次,每次随机抽取一些设置了过期时间的 key(这边注意不是检查所有设置过期时间的key,而是随机抽取部分),检查是否过期,如果发现过期了就直接删除。
该定时任务的具体流程如下:
- 定时serverCron方法去执行清理,执行频率根据redis.conf中的hz配置的值
- 执行清理的时候,不是去扫描所有的key,而是去扫描所有设置了过期时间的key(redisDb.expires)
- 如果每次去把所有过期的key都拿过来,那么假如过期的key很多,就会很慢,所以也不是一次性拿取所有的key
- 根据hash桶的维度去扫描key,扫到20(可配)个key为止。假如第一个桶是15个key ,没有满足20,继续扫描第二个桶,第二个桶20个key,由于是以hash桶的维度扫描的,所以第二个扫到了就会全扫,总共扫描35个key
- 找到扫描的key里面过期的key,并进行删除
- 删除完检查过期的 key 超过 25%,继续执行4、5步

其他注意点:
- 为何不扫描所有key进行过期缓存元素删除:Redis本身就是高速缓存,如果每次检查大量的key,无论在CPU和内存的的使用率上都会特别高,Redis集群越大,风险越大。
- 分片模式下的删除同步:无论定时删除还是惰性删除。master 会生成删除的指令记录到 AOF 和 slave 节点。
相关文章:
Redis过期数据的删除策略
1 介绍 Redis 是一个kv型数据库,我们所有的数据都是存放在内存中的,但是内存是有大小限制的,不可能无限制的增量。 想要把不需要的数据清理掉,一种办法是直接删除,这个咱们前面章节有详细说过;另外一种就是…...
如何使用CSS实现一个拖拽排序效果?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 实现拖拽排序效果的CSS和JavaScript示例⭐ HTML 结构⭐ CSS 样式 (styles.css)⭐ JavaScript 代码 (script.js)⭐ 实现说明⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦…...
leetcode 118.杨辉三角
⭐️ 题目描述 🌟 leetcode链接:https://leetcode.cn/problems/pascals-triangle/description/ 代码: class Solution { public:vector<vector<int>> generate(int numRows) {// 先开空间vector<vector<int>> v;v.…...
微服务框架之SpringBoot面试题汇总
微服务框架之SpringBoot面试题汇总 什么是Spring Boot? 多年来,随着新功能的增加,spring变得越来越复杂。Spring项目,我们必须添加构建路径或添加Maven依赖关系,配置应用程序服务器,添加spring配置。因此&…...
Promise详解
目录 一、前言:为什么会出现Promise?二、Promise是什么?2.1 Promise的初体验 三、使用Promise的好处?3.1 指定回调函数的方式更加灵活3.2 可以解决回调地狱问题,支持链式调用 四、Promise实例对象的两个属性五、resolve函数以及reject函数六、Promise…...
Oracle 查询(当天,月,年)的数据
Trunc 在oracle中,可利用 trunc函数 查询当天数据,该函数可用于截取时间或者数值,将该函数与 select 语句配合使用可查询时间段数据 查询当天数据 --sysdate是获取系统当前时间函数 --TRUNC函数用于截取时间或者数值,返回指定的…...
什么是梯度下降
什么是梯度下降 根据已有数据的分布来预测可能的新数据,这是回归 希望有一条线将数据分割成不同类别,这是分类 无论回归还是分类,我们的目的都是让搭建好的模型尽可能的模拟已有的数据 除了模型的结构,决定模型能否模拟成功的关键…...
开黑啦kook 机器人开发 PHP swoole Liunx 服务器(宝塔)
安装环境 PHP 拓展 直接使用 宝塔一键安装 (Windows系统不支持) 设置命令行的PHP版本避免执行脚本时 获取不到 swoole 检查swoole是否安装成功 获取官方SDK GitHub - kaiheila/php-bot: 开黑啦机器人的php版本https://github.com/kaiheila/php-bot 配…...
Vue 中hash 模式与 history 模式的区别
hash 模式: - 地址中永远带着 # 号,不美观。 - 兼容性比较好。 - 通过手机 app 分享地址时,如果 app 效验严格,该地址会被标记为不合法。 history 模式: - 地址干净,美观。 - 兼容性和 hash 模式相比…...
Dockerfile推送私有仓库的两个案例
一,编写Dockerfile制作Web应用系统nginx镜像,生成镜像nginx:v1.1,并推送其到私有仓库。 具体要求如下: (1)基于centos基础镜像; (2)指定作者信息; ÿ…...
【指标】指标公式大全,款款经典(建议珍藏)!-神奇指标网
三、指标源码: 1、连续三天高开高走的选股公式 count(o〉ref(c,1)andc>o,3)3; 2、连续3天每天的最低价都比前一天高 count(l〉ref(c,1),3)3; 3、周量缩小50%或40%或n&#x…...
面试题目收集
Zset排行榜功能如何设计key? key就设计成排行榜的名字,比如下面插入或者更新数据 Long zadd(final String key, final double score, final String member) key : 排行榜的名字 memeber : 用户 score : 用户的分数 项目…...
创建R包-2.1:在RStudio中使用Rcpp制作R-Package(更新于2023.8.23)
目录 0-前言 1-在RStudio中创建R包项目 2-创建R包 2.1通过R函数创建新包 2.2在RStudio通过菜单来创建一个新包 2.3关于R包创建的说明 3-添加R自定义函数 4-添加C函数 0-前言 目标:在RStudio中创建一个R包,这个R包中包含C函数,接口是Rc…...
chatGPT如何解释泽众PerformanceRunner性能测试工具?
PerformanceRunner 是一个性能测试工具,可以帮助测试人员进行性能测试。它的主要功能包括: 1. 脚本录制和回放: PerformanceRunner可以录制 HTTP/HTTPS 通信协议的脚本,并能够回放模拟真实用户的行为。通过录制和回放,…...
LA@向量组线性相关性
文章目录 向量组线性相关性线性相关线性无关多向量向量组线性相关单向量向量组的线性相关性单位向量向量组线性相关性双向量向量组的线性相关性双向量线性相关的几何意义三向量线性相关的几何意义包含零向量的向量组线性相关概念迁移:线性方程组和线性相关齐次线性方程组和向量…...
[k8s] 基于ubuntu22部署k8s1.28记录
k8s1.28部署已经不依赖docker了,所以不需要安装docker。同理:如果想查看镜像和运行容器,也不能用docker命令去查询了:需要使用crictl。不过crictl命令参数兼容docker,所以使用上手没有啥难度。 1. 配置安装源 根据k8…...
React 事件代理 和原生事件绑定混用:你的选择会导致什么问题?
在React开发中,事件处理是一个常见的任务。React提供了一个方便的事件系统,但有时我们可能会在React组件中与原生DOM事件一起使用。本文将讨论React的事件代理机制与原生事件绑定混用可能导致的一些问题。 React的事件代理 React采用了一种称为"事…...
使用阿里云国外和国内云服务器有什么注意事项?
使用阿里云的国外和国内云服务器时,有一些注意事项需要考虑: 地理位置:选择离你的用户或数据中心最近的地理位置,可以减少延迟和提高访问速度。对于国内用户,使用国内云服务器可能更好;对于国外用户&#…...
【计算机网络】【常考问题总结】
1. ping 127.0.0.1 后会发生什么? ping 127.0.0.1 ;ping 0.0.0.0 ; ping localhost 面试官问:断网了,还能ping通 127.0.0.1 吗?为什么?_kevin_tech的博客-CSDN博客 2. MTU,MMU是…...
前端基础(props emit slot 父子组件间通信)
前言:如何实现组件的灵活使用,今天学习组件封装用到的props、slot和emit。 目录 props 子组件 父组件 示例代码 slot 示例代码 作用域插槽 emit 示例代码 props 需要实现在其他组件中使用同一个子组件。 子组件 子组件(所谓子组件…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
