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.mzph.cn/news/857852.shtml

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

相关文章

MSPM0G3507 ——GPIO例程讲解2——simultaneous_interrupts

主函数: #include "ti_msp_dl_config.h"int main(void) {SYSCFG_DL_init();/* Enable Interrupt for both GPIOA and GPIOB ports */NVIC_EnableIRQ(GPIO_SWITCHES_GPIOA_INT_IRQN); //启用SWITCHES——A的中断 NVIC_EnableIRQ(GPIO_S…

【数据结构与算法】哈夫曼树,哈夫曼编码 详解

哈夫曼树的数据结构。 struct TreeNode {ElemType data;TreeNode *left, *right; }; using HuffmanTree TreeNode *;结构体包含三个成员: data 是一个 ElemType 类型的变量,用于存储哈夫曼树节点的数据。left 是一个指向 TreeNode 类型的指针&#xf…

强化学习中的自我博弈(self-play)

自我博弈(Self-Play)[1]是应用于智能体于智能体之间处于对抗关系的训练方法,这里的对抗关系指的是一方的奖励上升必然导致另一方的奖励下降。通过轮流训练双方的智能体就能使得双方的策略模型的性能得到显著提升,使得整个对抗系统…

CBA认证-业务架构师认证的尚方宝剑

CBA业务架构师认证是一种由业务架构师公会(Business Architecture Guild)授予的专业认证,全称为Certified Business Architect,简称CBA。以下是关于CBA业务架构师认证的主要信息和特点: 认证目的: CBA认证…

基于淘宝商城用户购物行为数据分析系统

摘 要 在电商行业高速发展的今天,用户购物行为数据量呈指数型增长,传统的数据处理架构已经无法满足于现如今的数据处理需求。针对于这样的需求本课题设计了一种基于淘宝的用户购物行为分析系统,旨在通过对大量数据进行分析处理进而深入研究用…

Portainer.io安装并配置Docker远程访问及CA证书

Portainer.io安装并配置Docker远程访问及CA证书 文章目录 Portainer.io安装并配置Docker远程访问及CA证书一.安装 Portainer.io2.启动容器 二.docker API远程访问并配置CA安全认证1.配置安全(密钥)访问2.补全CA证书信息3.生成server-key.pem4.创建服务端签名请求证书文件5.创建…

Redis的安装及详解

1.Redis介绍? 1.1 Redis是什么? Redis(Remote Dictionary Server,远程字典服务器)是一个开源免费的,用C语言编写的一个高性能的分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库。是当前最热门的…

uniapp(全端兼容) - 最新详细实现刻度尺组件效果,uni-app实现尺子打分及手指拖动刻度尺打分评分功能,可左右滑动刻度尺改变数值、带刻度尺滑块功能、

效果图 在uniapp微信小程序/手机h5网页网站/安卓app/苹果app/支付宝小程序/nvue等(全平台完美兼容)开发中,实现uniApp各端都兼容的 “刻度尺(横格尺 | 尺子)” 手势左右两侧拖动、手指滑动刻度尺功能,水平刻度尺,支持自定义尺子颜色、大小、刻度、滑动时的步进值、最大…

分享计算机msvcp100.dll,丢失或找不到的7个解决方法

msvcp100.dll是动态链接库文件对于执行使用 Microsoft Visual C 2010 编译器编译的应用程序至关重要。它包含了 C 标准库的实现,提供了应用程序运行时所需的核心功能,如输入/输出操作、字符串处理、数学运算和异常处理等。若系统中缺失或损坏此文件&…

【详细】一步一步实现一个BP神经网络-逐行代码解说

本文来自《老饼讲解-BP神经网络》https://www.bbbdata.com/ ​ 要如何使用代码实现一个BP神经网络呢? 下面跟随笔者,一步一步详细来实现,再对代码进行详细解说。 通过本文可以详细掌握怎么使用matlab来实现一个BP神经网络。 一、一步一步实…

# 消息中间件 RocketMQ 高级功能和源码分析(八)

消息中间件 RocketMQ 高级功能和源码分析(八) 一、消息中间件 RocketMQ 源码分析:实时更新消息消费队列与索引文件流程说明 1、实时更新消息消费队列与索引文件 消息消费队文件、消息属性索引文件都是基于 CommitLog 文件构建的&#xff0…

点击旋转箭头样式

实现效果&#xff1a; html界面&#xff0c;主要通过isdown来控制箭头是上还是下 <el-popoverplacement"bottom"trigger"click":visible-arrow"false"v-model"isdown"popper-class"user-popover"><divslot"re…

热点观察 | 全球社交应用IAP收入持续上升,小游戏、短剧出海赛道火热!

2024年进度条即将过半&#xff0c;回顾上半年&#xff0c;“Sora横空出世”、“短剧出海”、“小游戏爆款不断"给了我们太多惊喜&#xff0c;虽说如今市场竞争激烈、行业日趋饱和&#xff0c;但新技术、新需求也在快速跟上。下面&#xff0c;我们就来盘一盘近期全球手游和…

【数据库】数据库脚本编写规范(Word原件)

编写本文档的目的是保证在开发过程中产出高效、格式统一、易阅读、易维护的SQL代码。 1 编写目的 2 SQL书写规范 3 SQL编写原则 软件全套资料获取进主页或者本文末个人名片直接获取。

Linux常用命令(15)—grepsed命令(有相关截图)

写在前面&#xff1a; 最近在学习Linux命令&#xff0c;记录一下学习Linux常用命令的过程&#xff0c;方便以后复习。仅供参考&#xff0c;若有不当的地方&#xff0c;恳请指正。如果对你有帮助&#xff0c;欢迎点赞&#xff0c;关注&#xff0c;收藏&#xff0c;评论&#xf…

常见调试器介绍

目录 常见调试器 1.1 ST-Link 1.2 DAPLink 1.3 JLink 常见调试器 市面上有很多的调试器&#xff0c;下面是大家比较常见的一些调试器&#xff0c; 比如&#xff1a;ST-Link、DAPLink、JLink、Ulink等 1.1 ST-Link ST-Link是一种用于STM8及STM32系列单片机的调试器和下载…

在线预览多类型文件_全栈

目录 一、下载运行项目 二、项目功能 三、前端项目引用 四、文件预览样式更改 在做项目时经常用到在线预览文件&#xff0c;给大家介绍一个好用的在线预览文件项目。使用技术是后端Java&#xff0c;前端Freemarker模板。 FreeMarker 特别适应与 MVC 模式的 Web 应用&#x…

Python --- 如何修改Jupyter Notebook保存文件的路径?

如何修改Jupyter Notebook在本地保存文件的默认路径&#xff1f; 一直以来都比较喜欢jupter notebook&#xff0c;自从用了以后就爱上了。平时用的时候&#xff0c;因为大多都是临时调用&#xff0c;每次在界面里直接new一个新的file就开干。 曾经也想过我创建的这些python文件…

【arm扩容】新硬盘挂载操作说明

背景&#xff1a; 未经过扩容的arm设备不满足移植大镜像的条件。 需求&#xff1a; 我们要对arm设备扩容&#xff0c;现在要将一个500G的硬盘挂进去。而且要按照老arm设备的挂法&#xff0c;保持相同的目录结构。配置这台机器。 下面老arm设备的硬盘挂载相关信息。 lsblk …

SSRF(2)

Gopher协议的利用 gopher协议是ssrf利用中最强大的协议 gopher协议支持发出GET、POST请求&#xff1a; 可以先截获get请求包和post请求包&#xff0c;再构成符合gopher协议的请求。 默认端口为70,一般需发送到80端口 如果发起post请求&#xff0c;回车换行需要使用%0D%0A&…