Redis中过期策略是怎么样的
最近发现不少小伙伴都对数据库很感兴趣,所以今天继续给大家介绍数据库相关的知识,本文《Redis中过期策略是怎么样的》主要内容涉及到等等知识点,希望能帮到你!当然如果阅读本文时存在不同想法,可以在评论中表达,但是请勿使用过激的措辞~
保存过期时间
Redis可以为每个key设置过期时间,会将每个设置了过期时间的key放入一个独立的字典中。【相关推荐:Redis视频教程】
typedef struct redisDb { int id; //id是数据库序号,为0-15(默认Redis有16个数据库) long avg_ttl; //存储的数据库对象的平均ttl(time to live),用于统计 dict *dict; //存储数据库所有的key-value dict *expires; //存储key的过期时间 dict *blocking_keys;//blpop 存储阻塞key和客户端对象 dict *ready_keys;//阻塞后push 响应阻塞客户端 存储阻塞后push的key和客户端对象 dict *watched_keys;//存储watch监控的的key和客户端对象 } redisDb;
dict 用来维护一个 Redis 数据库中包含的所有 Key-Value 键值对,expires则用于维护一个 Redis 数据库中设置了失效时间的键(即key与失效时间的映射)。注意这里的失效时间是用毫秒的时间戳表示的,比如2022-01-02 22:45:02过期则value为1641134702000
当我们使用expire命令设置一个key的失效时间时,Redis 首先到 dict 这个字典表中查找要设置的key是否存在,如果存在就将这个key和失效时间添加到 expires 这个字典表。
当我们使用setex命令向系统插入数据时,Redis 首先将 Key 和 Value 添加到 dict 这个字典表中,然后将 Key 和失效时间添加到 expires 这个字典表中。注意setex只能用于字符串。
简单地总结来说就是,设置了失效时间的key和具体的失效时间全部都维护在 expires 这个字典表中。
设置过期时间
expire的使用
expire命令的使用方法如下: expire key ttl(单位秒)
127.0.0.1:6379> expire name 2 #2秒失效 (integer) 1 127.0.0.1:6379> get name (nil) 127.0.0.1:6379> set name zhangfei OK 127.0.0.1:6379> ttl name #永久有效 (integer) -1 127.0.0.1:6379> expire name 30 #30秒失效 (integer) 1 127.0.0.1:6379> ttl name #还有24秒失效 (integer) 24 127.0.0.1:6379> ttl name #失效 (integer) -2
Redis有四个不同的命令可以用于设置键的生存时间(键可以生存多久)或过期时间(键什么时候会被删除):
expire 命令用于将键key的生存时间设置为ttl秒
pexpire 命令用于将键key的生存时间设置为ttl毫秒
expireat 命令用于将键key的过期时间设置为timestamp所指定的秒数时间戳
pexpireat 命令用于将键key的过期时间设置为timestamp所指定的毫秒数时间戳
注意expire、pexpire、expireat最终实现都是通过pexpireat实现的,也就是说无论客户端执行哪个命令,都会Redis都会转换成pexpireat命令执行。所以expires字典中存的时间是用毫秒时间戳表示的键的过期时间。
过期策略
如果一个键过期了,那什么时候被删除呢?
有三种过期策略
定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作。(创建定时器删除)
惰性删除:放任键的过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。(使用的时候删除)
定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面过期的键。至于要删除多少过期键,以及要检查多少个数据库,则有算法决定。(定期扫描删除)
定时删除
优点
1、对内存最友好:通过使用定时器,可以保证过期的键会尽可能快地被删除,释放所占内存
缺点
1、对cpu最不友好:在过期键比较多的情况下,删除过期键这一行为可能会占用相当一部分cpu的时间,对服务器的响应时间和吞吐量造成影响。
惰性删除
优点
1、对cpu最友好:只有在取出键的时候才会对过期键进行检查,即不需要cpu定期扫描,也不需要创建大量的定时器。
缺点
1、对内存最不友好:如果一个键已经过期,但是后面不会被访问到的话,那么就一直保留在数据库中。如果这样的键过多,无疑会占用很大的内存。
定期删除
定期删除是上面的定时删除和惰性删除的一中折中方案。
优点
1、定期删除每隔一段时间执行一次过期键操作,并通过限制删除操作执行的时长和频率来减少删除操作对cpu时间的影响。
2、通过删除过期键,能有效的减少因为过期键而带来的内存浪费
缺点 难以确定删除操作执行的时长和频率
1、如果删除操作执行得太频繁,或者执行的时间太长,定期删除策略就会退化成定时删除,以至于占用太多cpu的执行时间。
2、如果删除操作执行的时间太少,或执行时间太短,定期删除策略又会和惰性删除一样,出现内存浪费。
Redis的过期策略
Redis使用是惰性删除和定期删除两种策略:通过配好使用这两种策略,服务器可以很好地在合理使用cpu时间和避免浪费内存空间之间取得平衡。
惰性删除策略的实现
过期键的惰性删除删除策略由db.c/expireIfNeeded函数实现,所有读写数据库的Redis命令在执行之前都会调用expireIfNeed函数对输入键进行检查:
如果键已经过期,那么expireIfNeeded函数将键删除
如果键未过期,那么expireIfNeeded函数不做操作
命令调用expireIfNeeded函数过程如下图
另外因为每个被访问的键都可能被删除,所以每个命令都必须能同时处理键存在以及不存在的情况。 下图表示get命令的执行过程
定期删除策略的实现
过期键的定期删除策略由redis.c/activeExpireCycle函数实现,每当Redis的服务器周期性操作redis.c/serverCron函数执行时,activeExpireCycle函数就会被调用,它在规定时间内,分多次遍历服务器中各个数据库。
Redis 默认每秒进行 10 次过期扫描,过期扫描不会遍历过期字典中所有的 key, 而是采用了一种简单的贪心策略,步骤如下。
(1)从过期字典中随机选出 20个 key。
(2)删除这 20 个 key 中已经过期的 key。
(3)如果过期的 key的比例超过 1/4,那就重复步骤 (1)。 同时,为了保证过期扫描不会出现循环过度,导致结程卡死的现象,算法还增加了扫描时间的上限,默认不会超过 25ms。
假设一个大型的 Redis 实例中所有的 key 在同一时间过期了,会出现怎样的结果呢?
消耗cpu
Redis 会持续扫描过期字典(循环多次),直到过期字典中过期的key变得稀疏,才会停止(循环次数明显下降)。
导致请求卡顿或超时
当客户端请求到来时,服务器如果正好进入过期扫描状态,客户端的请求将会等待至少 25ms 后才会进行处理,如果客户端将超时时间设置得比较短,比如 10ms,那么就会出现大量的连接因为超时而关闭 ,业务端就会出现很多异常
所以一定要注意过期时间,如果有大批量的key过期,要给过期时间设置一个随机范围,而不能全部在同一时间过期。
今天关于《Redis中过期策略是怎么样的》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于redis的内容请关注golang学习网公众号!

- 上一篇
- 如何应用kubernetes工作负载

- 下一篇
- PHP 函数如何创建文档?
-
- 数据库 · Redis | 11小时前 |
- Redis带宽瓶颈检测与优化方法
- 482浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- RedisSentinel高可用配置详解
- 174浏览 收藏
-
- 数据库 · Redis | 19小时前 |
- 多租户Redis安全隔离方法详解
- 474浏览 收藏
-
- 数据库 · Redis | 19小时前 |
- Redis性能监控工具推荐与使用方法
- 335浏览 收藏
-
- 数据库 · Redis | 20小时前 |
- Redis慢查询分析与优化方法
- 383浏览 收藏
-
- 数据库 · Redis | 1天前 |
- Redis集群节点规划与部署全解析
- 501浏览 收藏
-
- 数据库 · Redis | 2天前 |
- Redis与MySQL缓存同步方法解析
- 245浏览 收藏
-
- 数据库 · Redis | 2天前 |
- Redis性能监控工具有哪些
- 124浏览 收藏
-
- 数据库 · Redis | 2天前 |
- RedisList队列优化方法分享
- 378浏览 收藏
-
- 数据库 · Redis | 2天前 |
- Redis位图实现用户签到优化方案
- 322浏览 收藏
-
- 数据库 · Redis | 2天前 |
- Redis数据安全防护全攻略
- 112浏览 收藏
-
- 数据库 · Redis | 2天前 |
- Redis哈希技巧与实战应用
- 204浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 千音漫语
- 千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
- 103次使用
-
- MiniWork
- MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
- 97次使用
-
- NoCode
- NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
- 116次使用
-
- 达医智影
- 达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
- 106次使用
-
- 智慧芽Eureka
- 智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
- 108次使用
-
- redis复制有可能碰到的问题汇总
- 2023-01-01 501浏览
-
- 使用lua+redis解决发多张券的并发问题
- 2023-01-27 501浏览
-
- Redis应用实例分享:社交媒体平台设计
- 2023-06-21 501浏览
-
- 使用Python和Redis构建日志分析系统:如何实时监控系统运行状况
- 2023-08-08 501浏览
-
- 如何利用Redis和Python实现消息队列功能
- 2023-08-16 501浏览