百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

Redis的过期策略(redis过期策略配置参数)

mhr18 2024-10-25 12:35 20 浏览 0 评论

前言

Redis 是一种常用的内存数据库,它可以为存储的 key 设置过期时间。那么,Redis 是如何处理过期的 key 的呢?它会不会影响 Redis 的单线程性能呢?要回答这些问题,我们需要先了解 Redis 的过期策略和内存淘汰机制。

Redis 的过期策略是结合定期删除和懒惰删除来实现的。

定期删除策略

Redis 的定期删除策略是一种平衡的方法,它定时地检查 Redis 库中的过期数据,采用随机抽样的方法,根据过期数据的比例来调整删除的速度。

过期数据的比例是指 Redis 在定期删除策略中,根据每次随机抽样的键中有多少是过期的来决定是否继续删除。如果过期的键比例超过 1/4,就继续抽样和删除。这样可以根据过期数据的密集程度来控制删除的频率,避免过多占用 CPU 资源或内存空间。

例如:

Redis 会将每个设置了过期时间的 key 存入到一个单独的字典中,默认每 100ms 执行一次过期扫描:

  1. 随机抽取 20 个 key
  2. 删除这 20 个 key 中已经过期的 key
  3. 如果过期的 key 比例超过 1/4,就重复步骤 1,继续删除。

为什不扫描所有的 key?

Redis,作为一个单线程系统,全面扫描所有键值对可能会大幅度地影响性能。因此,Redis 限制每次过期扫描的最大耗时,这个限制默认是 25ms。

如果用户将操作超时设置得太短,比如 10ms,那么许多连接可能会由于超时而关闭,导致应用出现许多异常。此时,Redis 的慢查询日志可能并没有任何记录,因为慢查询记录的只是命令的处理时间,而不包括等待时间。

当大量键值对在同一时刻过期时,Redis 会多次扫描过期字典,直到过期键的比例低于四分之一。这可能会导致短暂的系统卡顿,尤其在并发请求高的情况下,这可能引发所谓的缓存雪崩。

设置25ms为什么还会出现缓存雪崩

因为Redis运行在单线程模式中,所有的请求处理都必须按照顺序进行。为了平衡过期键的删除和服务的响应性,Redis限制了每次过期扫描的时间,上限是25毫秒。因此,每个请求的处理时间最多为25毫秒。假设有100个请求等待处理,那么总的处理时间就可能高达2500毫秒。

然而,如果同时有大量的键过期,这就可能导致Redis需要花费更多的时间来进行扫描和删除操作。因此,为了避免这种情况,建议将键的过期时间设置为一个随机范围,这样就可以让过期的键在不同的时间点进行过期,从而降低单次扫描的压力,提高Redis的处理效率。

从库的过期策略

Redis的从库采取被动方式处理键值过期,即它不会主动去扫描和删除过期的键。当从库收到读取请求时,它会将请求发送到主库处理。在主库端,会检查相关键是否已过期,如果是,那么主库会删除这个键,并把删除操作同步给所有从库。这样的处理方式意味着从库可以避免进行过期扫描,进一步减轻了从库的处理负荷。

惰性删除策略

与定期删除不同,懒惰删除策略并不会定时地去扫描和删除过期的键,而是在每次访问键时,检查该键是否已经过期,如果已经过期,那么就删除它。

它对比定期删除策略的优点?

可以节省处理器时间,因为只有在键被访问时,Redis才会去检查并删除过期的键。这种策略在很多情况下都能有效地处理过期的键,因为很多过期的键可能永远都不会被访问,因此没有必要花费时间去删除它们。

然而,懒惰删除策略的缺点在于可能会导致过期的键占用内存空间。因为只有在键被访问时,Redis才会删除它,如果一个过期的键一直没有被访问,那么它就会一直占用内存空间,这在内存紧张的环境下可能会成为一个问题。为了解决这个问题,Redis通常会结合定期删除策略,以确保及时地删除过期的键。

异步删除

在绝大多数场景下,Redis的del命令可以快速地执行并且不会产生明显的延迟,因为它能直接回收目标对象的内存。但是,当我们需要删除一个非常大的对象,例如,一个拥有数百万元素的哈希表,或者在使用FLUSHDBFLUSHALL命令来删除一个包含大量键值对的数据库时,这个删除操作就可能引起单线程的阻塞。

为了解决这个问题,从Redis 4.0开始,引入了一个名为lazyfree的机制。这个机制能将删除键值对或整个数据库的操作交给后台线程处理,以此最大程度地避免对Redis主线程的阻塞。

内存淘汰机制

以下是Redis支持的数据淘汰策略:

  1. noeviction(不删除):这种策略下,当内存不足时,Redis不会删除任何数据。如果达到最大内存限制,任何写入数据的操作将会返回一个错误。这种策略适用于那些希望确保数据持久性并手动管理内存的场景。
  2. allkeys-lru(Least Recently Used,最近最少使用):在这种策略下,Redis会根据最近的访问频率删除数据。在需要释放内存时,Redis会从所有键中选择最近最少使用的键进行淘汰。这种策略适用于大多数场景,尤其是那些需要缓存数据并根据数据访问频率来决定淘汰顺序的应用。
  3. volatile-lru(最近最少使用,只针对设置了过期时间的键):与allkeys-lru类似,但仅针对设置了过期时间的键进行淘汰。这种策略适用于那些希望保留永久数据并仅根据访问频率淘汰具有过期时间的数据的场景。
  4. allkeys-random(随机删除):在这种策略下,Redis会在需要释放内存时从所有键中随机选择一个进行淘汰。这种策略可能导致一些重要但访问频率较低的数据被删除,因此在选择时需要谨慎。
  5. volatile-random(随机删除,只针对设置了过期时间的键):与allkeys-random类似,但仅针对设置了过期时间的键进行淘汰。这种策略适用于那些希望保留永久数据并随机淘汰具有过期时间的数据的场景。
  6. volatile-ttl(根据TTL值淘汰,只针对设置了过期时间的键):在这种策略下,Redis会根据键的剩余生存时间(TTL)进行淘汰。具有较短剩余生存时间的键将优先被淘汰。这种策略适用于那些希望基于数据的剩余生存时间来决定淘汰顺序的场景。

相关推荐

B站收藏视频失效?mybili 收藏夹备份神器完整部署指南

本内容来源于@什么值得买APP,观点仅代表作者本人|作者:羊刀仙很多B站用户都有过类似经历:自己精心收藏的视频突然“消失”,点开一看不是“已被删除”,就是“因UP主设置不可见”。而B站并不会主动通知...

中间件推荐初始化配置

Redis推荐初始化配置bind0.0.0.0protected-modeyesport6379tcp-backlog511timeout300tcp-keepalive300...

Redis中缓存穿透问题与解决方法

缓存穿透问题概述在Redis作为缓存使用时,缓存穿透是常见问题。正常查询流程是先从Redis缓存获取数据,若有则直接使用;若没有则去数据库查询,查到后存入缓存。但当请求的数据在缓存和数据库中都...

后端开发必看!Redis 哨兵机制如何保障系统高可用?

你是否曾在项目中遇到过Redis主服务器突然宕机,导致整个业务系统出现数据读取异常、响应延迟甚至服务中断的情况?面对这样的突发状况,作为互联网大厂的后端开发人员,如何快速恢复服务、保障系统的高可用...

Redis合集-大Key处理建议

以下是Redis大Key问题的全流程解决方案,涵盖检测、处理、优化及预防策略,结合代码示例和最佳实践:一、大Key的定义与风险1.大Key判定标准数据类型大Key阈值风险场景S...

深入解析跳跃表:Redis里的"老六"数据结构,专治各种不服

大家好,我是你们的码农段子手,今天要给大家讲一个Redis世界里最会"跳科目三"的数据结构——跳跃表(SkipList)。这货表面上是个青铜,实际上是个王者,连红黑树见了都要喊声大哥。...

Redis 中 AOF 持久化技术原理全解析,看完你就懂了!

你在使用Redis的过程中,有没有担心过数据丢失的问题?尤其是在服务器突然宕机、意外断电等情况发生时,那些还没来得及持久化的数据,是不是让你夜不能寐?别担心,Redis的AOF持久化技术就是...

Redis合集-必备的几款运维工具

Redis在应用Redis时,经常会面临的运维工作,包括Redis的运行状态监控,数据迁移,主从集群、切片集群的部署和运维。接下来,从这三个方面,介绍一些工具。先来学习下监控Redis实时...

别再纠结线程池大小 + 线程数量了,没有固定公式的!

我们在百度上能很轻易地搜索到以下线程池设置大小的理论:在一台服务器上我们按照以下设置CPU密集型的程序-核心数+1I/O密集型的程序-核心数*2你不会真的按照这个理论来设置线程池的...

网络编程—IO多路复用详解

假如你想了解IO多路复用,那本文或许可以帮助你本文的最大目的就是想要把select、epoll在执行过程中干了什么叙述出来,所以具体的代码不会涉及,毕竟不同语言的接口有所区别。基础知识IO多路复用涉及...

5分钟学会C/C++多线程编程进程和线程

前言对线程有基本的理解简单的C++面向过程编程能力创造单个简单的线程。创造单个带参数的线程。如何等待线程结束。创造多个线程,并使用互斥量来防止资源抢占。会使用之后,直接跳到“汇总”,复制模板来用就行...

尽情阅读,技术进阶,详解mmap的原理

1.一句话概括mmapmmap的作用,在应用这一层,是让你把文件的某一段,当作内存一样来访问。将文件映射到物理内存,将进程虚拟空间映射到那块内存。这样,进程不仅能像访问内存一样读写文件,多个进程...

C++11多线程知识点总结

一、多线程的基本概念1、进程与线程的区别和联系进程:进程是一个动态的过程,是一个活动的实体。简单来说,一个应用程序的运行就可以被看做是一个进程;线程:是运行中的实际的任务执行者。可以说,进程中包含了多...

微服务高可用的2个关键技巧,你一定用得上

概述上一篇文章讲了一个朋友公司使用SpringCloud架构遇到问题的一个真实案例,虽然不是什么大的技术问题,但如果对一些东西理解的不深刻,还真会犯一些错误。这篇文章我们来聊聊在微服务架构中,到底如...

Java线程间如何共享与传递数据

1、背景在日常SpringBoot应用或者Java应用开发中,使用多线程编程有很多好处,比如可以同时处理多个任务,提高程序的并发性;可以充分利用计算机的多核处理器,使得程序能够更好地利用计算机的资源,...

取消回复欢迎 发表评论: