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

从理论到实践,深入解析Redis过期删除策略与内存淘汰机制

mhr18 2024-10-24 11:09 21 浏览 0 评论

我们知道,Redis是一款高性能的KV型分布式内存数据库。但是,由于内存资源始终是有限的,因此它必须遵循约定地过期Key删除策略与内存淘汰机制来保障内存资源的合理分配,从而使系统能够高效稳定地运行。


1. 过期删除策略

在Redis中,它使用了“定期删除策略+惰性删除策略”来实现过期删除策略,定期删除策略是集中处理,而惰性删除策略是零散处理。

Redis 内部维护了一个独立的过期字典用于存储所有过期的 Key,Redis 会将每个设置了过期时间的 Key 放入到这个独立的过期字典中。

Redis 会定期地遍历过期字典,并删除其中过期的 Key。为了减少删除操作对 Redis 性能的影响,Redis 采用了分步删除(lazy delete)的方式:每次只删除少量的过期 Key,直到全部删除完毕。

除了定期地遍历过期字典删除过期Key之外,Redis还会使用惰性删除策略来删除过期的 Key,即Redis 接收到一个读写操作请求时,会首先检查该 Key 是否过期,如果过期了就立即删除。

1.1 定期删除策略

定期删除策略指定期每隔一段时间执行一次过期键删除操作,并通过限制删除操作执行时长和频率来减少删除操作对CPU时间的影响。

它可以通过redis.conf配置文件中的hz来进行配置,如图1所示:

如图1所示,Redis 默认每 1 秒执行10次过期扫描,也就是每 100 ms 执行一次。每次执行过期扫描并不会遍历过期字典中的所有Key,而是采用了一种简单的贪心策略,如图2所示:

如图2所示,定期删除策略的执行流程为:

  • 1)根据redis.conf中的hz配置的执行频率值,定时serverCron方法去执行清理;
  • 2)从过期字典中随机选择20个已经过期的Key;
  • 3)删除已经选择的这20个已经过期的 Key;
  • 4)删除完成之后,继续检查过期的Key的比率是否超过25%,如果超过,继续重复执行“2)与3)”,否则结束。

在redis.conf配置文件中,hz参数的取值范围是1~500。在设置hz参数时需要注意的是,如果删除操作执行次数过多、执行时间太长,就会导致占用大量CPU资源去进行删除操作;如果删除操作次数太少、执行时间短,就会导致内存资源被持续占用,得不到释放。通常情况下,不建议超过100,只有在请求延时非常低的情况下可以将值提升到100。

1.2 惰性删除策略

对于惰性删除策略,它相对比较简单,当Redis客户端进行读写操作请求时,先检查一下Key是否过期,如果过期则立即删除,并且不再提供值返回给客户端。相对于定期删除策略,惰性删除策略不会在特定的时间点去主动删除过期Key,而是等到客户端尝试访问它的时候再判断Key是否过期。

由此可见,惰性删除策略对CPU比较友好,但也可能会导致过多过期键长时间得不到清理并被积压,从而增加了内存开销,使占用的内存得不到及时的释放。因此,只有当Key失效而又没有被占用太长的时间时,才能体现出它的优越性。

最后,在Redis主从架构中还需要小心主从不同步带来的过期Key删除问题:即一个Slave节点因网络等问题而未与Master进行及时同步,此时如果Master上执行了过期Key删除操作并未及时同步给Slave节点。这时,这些Master删除的过期Key因未同步删除操作的原因仍会存在于Slave节点上,从而带来了一系列安全隐患,因此要注意处理这种情况。


2. 内存淘汰机制

2.1 内存淘汰策略概述

当 Redis 达到最大内存限制时,它会根据配置好的内存淘汰策略决定哪些Key被删除。Redis 提供的内存淘汰策略有如下8种:

1)noeviction

它是Redis系统默认的内存淘汰策略,该策略表示当内存不足以容纳新写入数据时,新的写操作会被拒绝,Redis会返回错误。这样,我们就可以保证已有数据的安全,同时系统开发者或运维人员也会得到明确的信号去增加Redis的内存,或者寻找其他的解决方案。

因此,在任何对数据的完整性和可靠性有严格要求,不能接受任何形式数据丢失的场景中,应该选择noeviction作为Redis的内存淘汰策略。

2)allkeys-lru

LRU 算法即为最近最少使用算法,该策略会根据LRU算法在内存不足以容纳新数据时,优先淘汰掉最长时间未被使用的缓存Key。

3)volatile-lru

该策略在过期的Key中使用LRU算法进行淘汰,即优先淘汰那些已经设定了过期时间且最近最少使用的Key,从而可以更好地利用有限的内存资源。

4)allkeys-random

该策略提供了一种简单有效,且执行效率都相对较高的方式来处理内存压力,它会在所有的Key中随机选择一个Key进行淘汰,它并不关心这个Key是否设置了过期时间,也不关心这个Key被访问的频率或者时间。因此,由于所有数据都有可能被随机淘汰,这就避免了某些数据因为访问频率低而被频繁淘汰的结果,从而在一定程度上保证了所有数据在Redis中的生存机会均等。

5)volatile-random

该策略同样并不考虑缓存Key被访问的频率或者时间,会从那些已设置过期时间的Key中随机选择一个进行删除,从而确保了那些重要的、永久的数据Key不会被删除。

6)volatile-ttl

该策略会在设置了过期时间的Key中,优先删除 TTL (Time To Live) 值最小的键,也就是最快过期的键。

7)allkeys-lfu

LFU 算法即为最不常用算法(根据使用频率进行计算),该策略根据LFU 算法将优先删除那些最不常用的Key。当内存达到上限时,Redis会计算每个Key的使用频率,并删除使用频率最低的Key。

8)volatile-lfu

该策略会从哪些设置了过期时间的Key中,优先淘汰使用频率最低的Key。如果存在一些Key没有设置过期时间,那么这些Key将永远不会被淘汰,即使内存已经达到了上限。因此,在使用该策略时,一定要确保所有的键都设置了合理的过期时间。


2.2 相关操作与设置

1)获取Redis能使用的最大内存大小

config get maxmemory

运行结果如下图所示:

2)获取Redis内存淘汰策略

config get maxmemory-policy

运行结果如下图所示:

3)在redis.conf配置文件中设置淘汰策略,如下图所示:

4)在redis.conf配置文件中设置内存限制,如下图所示:

5)通过命令方式设置内存淘汰策略与内存限制(这种方式仅限于临时生效,因此不推荐),如下所示:

# 设置内存淘汰策略 
config set maxmemory-policy allkeys-lru

#设置内存限制 
config set maxmemory 100mb

相关推荐

使用 Docker 部署 Java 项目(通俗易懂)

前言:搜索镜像的网站(推荐):DockerDocs1、下载与配置Docker1.1docker下载(这里使用的是Ubuntu,Centos命令可能有不同)以下命令,默认不是root用户操作,...

Spring Boot 3.3.5 + CRaC:从冷启动到秒级响应的架构实践与踩坑实录

去年,我们团队负责的电商订单系统因扩容需求需在10分钟内启动200个Pod实例。当运维组按下扩容按钮时,传统SpringBoot应用的冷启动耗时(平均8.7秒)直接导致流量洪峰期出现30%的请求超时...

《github精选系列》——SpringBoot 全家桶

1简单总结1SpringBoot全家桶简介2项目简介3子项目列表4环境5运行6后续计划7问题反馈gitee地址:https://gitee.com/yidao620/springbo...

Nacos简介—1.Nacos使用简介

大纲1.Nacos的在服务注册中心+配置中心中的应用2.Nacos2.x最新版本下载与目录结构3.Nacos2.x的数据库存储与日志存储4.Nacos2.x服务端的startup.sh启动脚...

spring-ai ollama小试牛刀

序本文主要展示下spring-aiollama的使用示例pom.xml<dependency><groupId>org.springframework.ai<...

SpringCloud系列——10Spring Cloud Gateway网关

学习目标Gateway是什么?它有什么作用?Gateway中的断言使用Gateway中的过滤器使用Gateway中的路由使用第1章网关1.1网关的概念简单来说,网关就是一个网络连接到另外一个网络的...

Spring Boot 自动装配原理剖析

前言在这瞬息万变的技术领域,比了解技术的使用方法更重要的是了解其原理及应用背景。以往我们使用SpringMVC来构建一个项目需要很多基础操作:添加很多jar,配置web.xml,配置Spr...

疯了!Spring 再官宣惊天大漏洞

Spring官宣高危漏洞大家好,我是栈长。前几天爆出来的Spring漏洞,刚修复完又来?今天愚人节来了,这是和大家开玩笑吗?不是的,我也是猝不及防!这个玩笑也开的太大了!!你之前看到的这个漏洞已...

「架构师必备」基于SpringCloud的SaaS型微服务脚手架

简介基于SpringCloud(Hoxton.SR1)+SpringBoot(2.2.4.RELEASE)的SaaS型微服务脚手架,具备用户管理、资源权限管理、网关统一鉴权、Xss防跨站攻击、...

SpringCloud分布式框架&amp;分布式事务&amp;分布式锁

总结本文承接上一篇SpringCloud分布式框架实践之后,进一步实践分布式事务与分布式锁,其中分布式事务主要是基于Seata的AT模式进行强一致性,基于RocketMQ事务消息进行最终一致性,分布式...

SpringBoot全家桶:23篇博客加23个可运行项目让你对它了如指掌

SpringBoot现在已经成为Java开发领域的一颗璀璨明珠,它本身是包容万象的,可以跟各种技术集成。本项目对目前Web开发中常用的各个技术,通过和SpringBoot的集成,并且对各种技术通...

开发好物推荐12之分布式锁redisson-sb

前言springboot开发现在基本都是分布式环境,分布式环境下分布式锁的使用必不可少,主流分布式锁主要包括数据库锁,redis锁,还有zookepper实现的分布式锁,其中最实用的还是Redis分...

拥抱Kubernetes,再见了Spring Cloud

相信很多开发者在熟悉微服务工作后,才发现:以为用SpringCloud已经成功打造了微服务架构帝国,殊不知引入了k8s后,却和CloudNative的生态发展脱轨。从2013年的...

Zabbix/J监控框架和Spring框架的整合方法

Zabbix/J是一个Java版本的系统监控框架,它可以完美地兼容于Zabbix监控系统,使得开发、运维等技术人员能够对整个业务系统的基础设施、应用软件/中间件和业务逻辑进行全方位的分层监控。Spri...

SpringBoot+JWT+Shiro+Mybatis实现Restful快速开发后端脚手架

作者:lywJee来源:cnblogs.com/lywJ/p/11252064.html一、背景前后端分离已经成为互联网项目开发标准,它会为以后的大型分布式架构打下基础。SpringBoot使编码配置...

取消回复欢迎 发表评论: