当前位置: 首页 > news >正文

Redis进阶 - 朝生暮死之Redis过期策略

在这里插入图片描述

概述

   Redis 是一种常用的内存数据库,其所有的数据结构都可以设置过期时间,时间一到,就会自动删除。你可以想象 Redis 内部有一个死神,时刻盯着所有设置了过期时间的 key,寿命一到就会立即收割。

image

  你还可以进一步站在死神的角度思考,会不会因为同一时间太多的 key 过期,以至于忙不过来。同时因为 Redis 是单线程的,收割的时间也会占用线程的处理时间,如果收割的太过于繁忙,会不会导致线上读写指令出现卡顿。所有在过期这件事上,Redis 非常小心。

一、Redis 数据过期

1.1 Redis中key的过期时间

  通过 EXPIRE key seconds 命令来设置数据的过期时间。返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间。在key上设置了过期时间后key将在指定的秒数后被自动删除。

127.0.0.1:6379> SETEX key 5 value
OK127.0.0.1:6379> ttl s
(integer) 5127.0.0.1:6379> GET key
"value"127.0.0.1:6379> GET key   ## 5 秒过后
(nil)

命令 TTL 用于返回给定键距离过期还有多长时间。注意:当key被DEL命令删除或者被SET、GETSET命令重置后与之关联的过期时间会被清除

  Redis 有四个命令可以设置键的生存时间(可以存活多久)和过期时间(什么时候到期),如下表所示:

命令说明
expire key seconds以秒为单位设置键的生存时间
pexpire key milliseconds以毫秒为单位设置键的生存时间
expireat key timestamp以秒为单位,设置键的过期 UNIX 时间戳
pexpireat key milliseconds-timestamp以毫秒为单位,设置键的过期 UNIX 时间戳

1.2 基于时间的过期策略

  • 在Redis中,可以使用EXPIRE和PEXPIRE命令为键设置生存时间,以秒或毫秒为单位。例如:

    # 设置多少秒后过期
    EXPIRE key seconds
    # 设置多少毫秒后过期
    PEXPIRE key milliseconds
    #  设置 key 过期时间的时间戳(unix timestamp) 以秒计
    EXPIREAT key timestamp
    # 设置 key 过期时间的时间戳(unix timestamp) 以毫秒计
    PEXPIREAT key milliseconds-timestamp
    
  • 可以使用TTL命令或PTTL命令来查看键的剩余生存时间(以秒或毫秒为单位)。例如:

    # 以秒为单位,返回给定 key 的剩余生存时间
    TTL key
    # 以毫秒为单位返回 key 的剩余的过期时间
    PTTL key
    
  • 可以使用PERSIST命令来取消键的生存时间,使其永久保存。例如:

    # 移除key的过期时间,key将保持永久
    PERSIST key
    

二、Redis数据过期策略

Redis的过期策略主要是通过定时删除、惰性删除和定期删除三种方式来管理键的生命周期。

数据过期策略
定时删除
定期删除
惰性删除
过期策略说明
定时删除为每个设置了过期时间的键创建一个定时器,一旦过期就立即删除。
但是这种方式可能会消耗大量的CPU资源,因此Redis默认不使用这种策略。
定期删除每隔一段时间随机抽查一些键,删除其中已经过期的键。
这种方式是前两种方式的折衷,结合了定时任务和惰性删除的优点,是Redis默认采用的策略。
惰性删除只有在访问键时,才会检查键是否过期,过期则删除。
这种方式可以最大程度地节省CPU资源,但可能会导致大量的空间浪费。

2.1 定时删除

  Redis 在设置键的过期时间时,创建一个定时事件,当过期时间到达时,由事件处理器自动执行键的删除操作。定时删除策略对内存是最友好的,因为它保证过期键会在第一时间被删除, 过期键所消耗的内存会立即被释放。但它对 CPU 时间是最不友好的,因为删除操作可能会占用大量的 CPU 时间,将 CPU 时间花在删除那些和当前任务无关的过期键上,从而影响缓存的响应时间和吞吐量,这种做法毫无疑问会是低效的,因此Redis默认不使用这种策略。

2.2 定期删除

  Redis 的定期删除策略是一种平衡的方法,它定时地检查 Redis 库中的过期数据,采用随机抽样的方法,根据过期数据的比例来调整删除的速度。过期数据的比例是指 Redis 在定期删除策略中,根据每次随机抽样的键中有多少是过期的来决定是否继续删除。如果过期的键比例超过 1/4,就继续抽样和删除。这样可以根据过期数据的密集程度来控制删除的频率,避免过多占用 CPU 资源或内存空间。
  Redis 会将每个设置了过期时间的 key 存入到一个单独的字典中,默认每秒进行 10 次过期检查一次数据库。每次检查数据库并不是遍历过期的所有 key,而是从数据库中随机抽取一定数量的 key 进行过期检查。接下来,详细说说 Redis 的定期删除的流程。

开始
随机抽取 20 个 key
删除已经过期的 key
判断执行时间
是否超过上限
stop
判断过期 key
比例超过 1/4

  此时,会有人问“至于为什么不扫描所有的 key?”,这个问题很简单,Redis 作为一个单线程系统,全面扫描所有键值对可能会大幅度地影响性能。因此,Redis 限制每次过期扫描的最大耗时,这个限制默认是 25ms。如果用户将操作超时设置得太短,比如 10ms,那么许多连接可能会由于超时而关闭,导致应用出现许多异常。此时,Redis 的慢查询日志可能并没有任何记录,因为慢查询记录的只是命令的处理时间,而不包括等待时间。当大量键值对在同一时刻过期时,Redis 会多次扫描过期字典,直到过期键的比例低于四分之一。这可能会导致短暂的系统卡顿,尤其在并发请求高的情况下,这可能引发所谓的缓存雪崩。

2.3 惰性删除

  与定期删除不同,懒惰删除策略并不会定时地去扫描和删除过期的键,而是在每次访问 key 时,才会判断该key是否已过期。若是过期则清除,并且删除的目标仅限于当前处理的键;如果没有过期,不做任何处理,然后返回正常的键值对给客户端。如下图所示:

开始
对 key 进行读写操作
判断 key
是否已过期
删除已过期 key
返回 null 给客户端
正常进行读写操作
返回数据客户端
结束

  惰性删除对比定期删除而言,可以节省处理器时间,因为只有在键被访问时,Redis 才会去检查并删除过期的键。这种策略在很多情况下都能有效地处理过期的键,因为很多过期的键可能永远都不会被访问,因此没有必要花费时间去删除它们。
  然而,惰性删除可能会导致过期的键占用内存空间。因为只有在键被访问时,Redis才会删除它,如果一个过期的键一直没有被访问,那么它就会一直占用内存空间,这在内存紧张的环境下可能会成为一个问题。举个例子, 对于一些按时间点来更新的数据, 比如日志(log), 在某个时间点之后, 对它们的访问就会大大减少, 如果大量的这些过期数据积压在数据库里面, 用户以为它们已经过期了(已经被删除了), 但实际上这些键却没有真正的被删除(内存也没有被释放), 那结果肯定是非常糟糕。

三、结语

  Redis 缓存的过期策略是保证缓存可靠性和性能的关键之一,通过设置键值对缓存、设置过期时间、取消过期时间和查看 Redis 内存使用情况等操作,可以实现对缓存的控制和管理。需要注意的是,在设置缓存过期时间时,应根据业务场景和数据类型来选择合适的时间。

在这里插入图片描述

相关文章:

Redis进阶 - 朝生暮死之Redis过期策略

概述 Redis 是一种常用的内存数据库,其所有的数据结构都可以设置过期时间,时间一到,就会自动删除。你可以想象 Redis 内部有一个死神,时刻盯着所有设置了过期时间的 key,寿命一到就会立即收割。 你还可以进一步站在死神…...

MySQL实训--原神数据库

原神数据库 er图DDL/DML语句查询语句存储过程/触发器 er图 DDL/DML语句 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;DROP TABLE IF EXISTS artifacts; CREATE TABLE artifacts (id int NOT NULL AUTO_INCREMENT,artifacts_name varchar(255) CHARACTER SET utf8 COLLATE …...

Retrieval-Augmented Generation for Large Language Models A Survey

Retrieval-Augmented Generation for Large Language Models: A Survey 文献综述 文章目录 Retrieval-Augmented Generation for Large Language Models: A Survey 文献综述 Abstract背景介绍 RAG概述原始RAG先进RAG预检索过程后检索过程 模块化RAGModules部分Patterns部分 RAG…...

【曦灵平台】深度体验百度智能云曦灵平台之数字人3.0、声音克隆、直播等功能,AI加持就是不一样,快来一起体验

目录 资产数字人 2D数字人克隆声音克隆 AI卡片更多功能总结推荐文章 资产 可进行人像与声音的定制,让数字人形象和声音成为我们的专属资产,用于后续的内容生产工作 数字人 这里拍摄的视频分辨率和帧率必须要确保是官方要求,这里博主通过第…...

如何使用GPT?初学者的指南

ChatGPT是一个非常先进的AI工具,它使用GPT-4架构,能够生成自然的语言回应。它的多功能性和理解复杂指令的能力,使得很多人用它来回答各种问题,就像用Google一样输入关键词。不过,ChatGPT还能做更多事情,下面…...

24年了 直播带货的未来如何?

32 个国家在取消电商, 那我国的电商呢,首先电商是不会被取缔的。直播电商会被严格的控制,比如有一家饼店,它线下的销售是 3000 万,线上抖音的销售是 5, 000 万。 这一类型小而精又专业的品牌企业,未来在抖…...

【神经网络】深入理解多层神经网络(深度神经网络

🎈个人主页:豌豆射手^ 🎉欢迎 👍点赞✍评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 深入理解多层神经网络&#x…...

CAS原理与JUC原子类

一、CAS基本原理 1、Unsafe类 (1)概念及作用:增强Java语言操作底层资源的能力,里面的方法多为native修饰的方法(基于C实现),不建议在代码中使用,不安全。 (2&#xff…...

【杂记-浅谈OSPF协议之RouterDeadInterval死区间隔】

OSPF协议之RouterDeadInterval死区间隔 一、RouterDeadInterval概述二、设置RouterDeadInterval三、RouterDeadInterval的重要性 一、RouterDeadInterval概述 RouterDeadInterval,即路由器死区间隔,它涉及到路由器如何在广播网络上发现和维护邻居关系。…...

【每日刷题】Day75

【每日刷题】Day75 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 1833. 雪糕的最大数量 - 力扣(LeetCode) 2. 面试题 17.14. 最小K个数 - 力扣…...

文件管理器加载缓慢-禁用文件类型自动发现功能

文件管理器加载缓慢-禁用文件类型自动发现功能 右键“Shell”项,选择新建“字符串值” “FolderType”,数值为 NotSpecified。...

.[nicetomeetyou@onionmail.org].faust深入剖析勒索病毒及防范策略

引言: 在数字化时代,网络安全问题日益凸显,其中勒索病毒无疑是近年来网络安全的重大威胁之一。勒索病毒以其独特的加密机制和恶意勒索行为,给个人和企业带来了巨大的经济损失和数据安全风险。本文将从勒索病毒的传播方式、攻击链、…...

Ardupilot开源代码之ExpressLRS性能实测方法

Ardupilot开源代码之ExpressLRS性能实测方法 1. 源由2. 测试效果3. 测试配置4. 总结5. 参考资料6. 补充 1. 源由 之前一直在讨论ExpressLRS性能的问题,有理论、模拟、实测。 始终缺乏完整的同一次测试的测试数据集,本章节将介绍如何在Ardupilot上进行获…...

Transformers是SSMs:通过结构化状态空间对偶性的广义模型和高效算法(二)

文章目录 6、针对SSD模型的硬件高效算法6.1、对角块6.2、低秩块6.3、计算成本 7、Mamba-2 架构7.1、块设计7.2、序列变换的多头模式7.3、线性注意力驱动的SSD扩展8、系统优化对于SSMs8.1、张量并行8.2、序列并行性8.3、可变长度 9、实证验证9.1、合成任务:联想记忆9…...

Segment any Text:优质文本分割是高质量RAG的必由之路

AI应用开发相关目录 本专栏包括AI应用开发相关内容分享,包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 AI应用开发流程概…...

IDEA 学习之 编译内存问题

目录 1. 正常的 IDEA build 日志2. 编译工具内存不足日志 (内存从小变大)2.1. 干脆无法启动2.2. Ant 任务执行报错2.3. 内存溢出:超出 GC 上限2.4. 内存溢出:超出 GC 上限,编译报错2.5. 内存溢出: 堆空间2.…...

如何将本地项目推送到gitee仓库

目录 为何用gitee管理自己项目: 如何将自己的项目推送到gitee仓库,步骤如下: 1.下载git 2.生成公钥 3.在gitee上添加公钥 4.在gitee上创建仓库 5.将本地项目推送到gitee仓库 为何用gitee管理自己项目: 1.可以使用多台电脑…...

产品经理基础入门

一、产品基础(需求收集、需求管理、需求分析、结构图、流程图、原型、PRD文档、用户画像、后台的角色管理) 产品经理定义: 1.市场分析:找准市场方向,确定哪个市场是值得进入的。 2.用户分析:针对目标市场…...

五子棋纯python手写,需要的拿去

import pygame,sys from pygame import * pygame.init()game pygame.display.set_mode((600,600)) gameover False circlebox [] # 棋盘坐标点存储 box [] def xy():for x in range(0,800//40): for y in range(0,800//40): box.append((x*40,y*40)) xy() defaultColor wh…...

C# Winform按钮避免重复点击以及解决WinForm中设置Enabled=False为什么还会响应Click事件

1、C# Winform按钮避免重复点击 代码如下 btn.Enablefalse; //执行任务的函数或代码 btn.Enabletrue; 在btn.Enabletrue前添加Application.DoEvents(); 就是让应用程序的消息队列自动走完(即在按钮为Ture前清空消息队列)。 2、解决WinForm中设置Enabl…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

uniapp中使用aixos 报错

问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...

【QT控件】显示类控件

目录 一、Label 二、LCD Number 三、ProgressBar 四、Calendar Widget QT专栏&#xff1a;QT_uyeonashi的博客-CSDN博客 一、Label QLabel 可以用来显示文本和图片. 核心属性如下 代码示例: 显示不同格式的文本 1) 在界面上创建三个 QLabel 尺寸放大一些. objectName 分别…...

Vue 实例的数据对象详解

Vue 实例的数据对象详解 在 Vue 中,数据对象是响应式系统的核心,也是组件状态的载体。理解数据对象的原理和使用方式是成为 Vue 专家的关键一步。我将从多个维度深入剖析 Vue 实例的数据对象。 一、数据对象的定义方式 1. Options API 中的定义 在 Options API 中,使用 …...