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 内存使用情况等操作,可以实现对缓存的控制和管理。需要注意的是,在设置缓存过期时间时,应根据业务场景和数据类型来选择合适的时间。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/357081.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“打造智能售货机系统,基于ruoyi微服务版本开源项目“

目录 # 开篇 售货机术语 1. 表设计说明 2. 页面展示 2.1 区域管理页面 2.2 合作商管理页面 2.3 点位管理页面 3. 建表资源 3.1 创建表的 SQL 语句(包含字段备注) 1. Region 表 2. Node 表 3. Partner 表 4. 创建 tb_vending_machine 表的 S…

Netty 入门实例

文章目录 1. 概述2. 代码实例2.1 服务端2.2 客户端2.3 运行截图 3. 整体结构4. 重要组件4.1 EventLoopGroup、EventLoop4.2 Handler & Pipeline4.3 ByteBuf 参考文献 1. 概述 Netty 是一款用于高效开发网络应用的 NIO 网络框架,它大大简化了网络应用的开发过程…

【鸿蒙】创建第⼀个鸿蒙项⽬

点击 Create Project 配置项目 开发工具界面 工程介绍

C语言第17篇:预处理详解

1、预定义符号 C语言设置了一些预定义符号,可以直接使用。预定义符号也是在预处理期间处理的。 __FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSI…

[巨详细]使用HBuilder-X新建uniapp项目教程

文章目录 安装HBuilder-X启动uniapp项目其他:下载预览浏览器下载终端插件想用uni-ui 安装HBuilder-X 详细步骤可看上文》》 启动uniapp项目 先打开HBuilder-X 点击新建项目 选择uniapp侧边栏,mian中的点击浏览 选择已经安装到本地的uniapp项目&#…

常用的设计模式

常用设计模式 ①单例模式(始终使用同一个对象)饿汉式/懒汉式DCL. synchronized. volatile(多线程可见性,不保原子性禁止指令重排) ②原型模式:(深拷贝和浅拷贝)使用深拷贝创建对象&#xff08…

本科生大厂算法岗实习经验复盘:从投递到面试的底层思维!

目录 投递渠道boss直聘官网邮箱内推 面试准备leetcode八股深挖项目自我介绍mock面试技巧答不出来怎么办coding反问 复盘技术交流群用通俗易懂方式讲解系列 节前,我们星球组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、参加社招和校招面…

2021-03-29:加密与解密

前段时间导师分配的任务主要是看《加密与解密》这本书,“书本写的很详细,认真看会看懂的!” 是的啊,书本写的很详细,可是作为一个没基础的小白看起来还是挺吃力的,概念一个接一个的出现,虽然看…

【Gradio】表格数据科学与图表-连接到数据库

简介 本指南解释了如何使用 Gradio 将您的应用程序连接到数据库。我们将连接到托管在 AWS 上的 PostgreSQL 数据库,但 gradio 对您连接到的数据库类型及其托管位置完全不可知。因此,只要您能够编写 Python 代码来连接到您的数据,您就可以使用…

无需安装就能一键部署Stable Diffusion 3?

一键部署使用SD3?让你的创作更加便捷! 前言 厚德云上架SD3! 距离Stable Diffusion 3的上线已经有一阵时间了。从上线至今SD3也是一直好评不断,各项性能的提升也让它荣获“最强开源新模型”的称号。成为了AI绘画设计师们新的香馍馍。 可对于SD…

K8S -理解StatefulSet - 部署有状态应用

什么是 有状态服务和 无状态服务 有状态服务(Stateful Service): 有状态服务是指在处理请求期间维护和跟踪用户状态或会话信息的服务。这意味着服务在多个请求之间保持状态,并且需要在请求之间共享和使用这些状态信息。通常&…

Vue67-Vuex简介

因为vuex是插件,所以,使用的时候:vue.use(插件名) 一、Vuex的意义和使用场景 红色的箭头,都是读数据。 若是,B、C、D都想修改A组件中的x数据(写):此时,A组件就是数据的接…

iOS18新增通话录音和应用锁!附升级教程及内置壁纸

一觉睡醒,iOS18终于是揭开面纱了,而且已经有测试版给开发者使用了。 不过还是建议咱们普通用户不要轻易尝试,而且在升级之前一定要用iMazing做个备份,以免测试系统出现问题,丢失数据。 这次WWDC2024与之前爆料完全一样…

【洛谷P3366】【模板】最小生成树 解题报告

洛谷P3366 -【模板】最小生成树 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出 orz。 输入格式 第一行包含两个整数 N , M N,M N,M,表示该图共有 N N N 个结点和 M M M 条无向边。 接下…

EasyX 文本输出(自定义)函数报错

EasyX 文本输出(自定义)函数报错记录 原因:EasyX与字符串相关的函数,都有字符集问题 UNICODE 多字节字符集

SpringCloud中Eureka和Nacos的区别和各自的优点

Eureka注册中心 Eureka作为一个注册中心,服务提供者把服务注册到注册中心,服务消费者去注册中心拉取信息, 然后通过负载均衡得到对应的服务器去访问。 服务提供者每隔30s向注册中心发送请求,报告自己的状态,当超过一定…

基于LangChain-Chatchat实现的RAG-本地知识库的问答应用[3]-参数配置详细版

基于LangChain-Chatchat实现的RAG-本地知识库的问答应用[3]-参数配置详细版 在开始参数配置之前,先执行以下脚本 python copy_config_example.py该脚本将会将所有config目录下的配置文件样例复制一份到config目录下,方便开发者进行配置。 接着,开发者可以根据自己的需求,对…

CSDN 自动上传图片并优化Markdown的图片显示

文章目录 完整代码一、上传资源二、替换 MD 中的引用文件为在线链接参考 完整代码 完整代码由两个文件组成,upload.py 和 main.py,放在同一目录下运行 main.py 就好! # upload.py import requests class UploadPic: def __init__(self, c…

2-13 基于matlab的电力负荷预测

基于matlab的电力负荷预测,论文阐述了负荷预测的应用研究现状,概括了负荷预测的特点及其影响因素,归纳了短期负荷预测的常用方法,并分析了各种方法的优劣;采用最小二乘支持向量机(LSSVM)模型&am…

docker desktop for mac os如何使用本地代理

在macbook上弄了个代理,然后按照网上所说的去配代理 然后测试下 docker pull busybox 结果无反应,超时。我去!!! 鼓捣了半天,看了docker官网,问了chatgpt ,按照它们所说的试了下也没…