Redis(2) : Redis的策略:定期删除、惰性删除和内存淘汰策略
mhr18 2024-10-24 11:09 21 浏览 0 评论
Redis 的过期策略主要是指管理和删除那些设定了过期时间的键,以确保内存的有效使用和数据的及时清理。 具体来说,Redis 有三种主要的过期策略:定期删除(Scheduled Deletion)、惰性删除(Lazy Deletion)和内存淘汰策略(Eviction Policies)。
1. 定期删除
Redis 的定期删除策略(Scheduled Deletion)的步骤如下:
- 设置定期任务:
Redis 会在后台线程中设置一个定期任务,用于扫描和删除过期键。这个任务会在特定的时间间隔内执行,默认每 100 毫秒运行一次。
- 随机抽样检查:
在每次定期任务执行时,Redis 会从已设置过期时间的键中随机抽取一部分键进行检查,而不是一次性检查所有键。这样可以减少对 CPU 的负载。
- 检查键的过期状态:
对于抽取的每一个键,Redis 会检查该键的过期时间。如果发现某个键已经过期,Redis 就会立即删除该键。
- 重复检查:
如果在一次扫描中发现了删除的健的占比超过了设置的阈值(比如:25%),那么 Redis 会继续进行下一轮的随机抽样检查,直到在一次扫描中没有找到任何过期的键为止。
- 调节扫描频率和负载:
为了防止定期删除任务占用过多的 CPU 资源,Redis 会根据上一次扫描中删除的过期键的数量来动态调整下一次扫描的强度。比如,如果上一次扫描删除了大量的过期键,那么下一次扫描的键数量可能会减少,反之亦然。
2. 惰性删除
Redis 的惰性删除策略(Lazy Deletion)的步骤如下:
- 访问键时检查过期状态:
当客户端对 Redis 发起读操作(如 GET)或写操作(如 SET)时,Redis 首先会检查被访问的键是否设置了过期时间。
- 获取当前时间:
Redis 获取当前的系统时间,用来与键的过期时间进行比较。
- 比较过期时间:
如果键的过期时间早于当前时间,说明该键已经过期。
- 删除过期键:
如果键已经过期,Redis 会立即删除该键,并返回一个特殊的响应(如返回 nil 表示键不存在,或其他与操作类型相关的结果)。
- 处理未过期键:
如果键未过期,Redis 会继续正常处理客户端的请求,返回键的值或执行相应的写操作。
示例
假设客户端向 Redis 发起一个 GET 操作来读取键 mykey 的值,惰性删除的详细步骤如下:
- 客户端发送 GET mykey:
客户端向 Redis 发送 GET mykey 命令。
- Redis 接收请求并查找键:
Redis 接收到请求后,查找键 mykey。
- 检查过期时间:
Redis 发现 mykey 设置了过期时间,获取当前时间。
- 比较当前时间和过期时间:
Redis 比较当前时间和 mykey 的过期时间。如果 mykey 的过期时间是 2024-06-01 12:00:00,当前时间是 2024-06-01 12:01:00,则 mykey 已经过期。如果当前时间是 2024-06-01 11:59:00,则 mykey 未过期。
- 删除过期键或返回值:
如果 mykey 已经过期,Redis 立即删除 mykey,并返回 nil 表示键不存在。
如果 mykey 未过期,Redis 返回 mykey 的值。
3. 内存淘汰
Redis 的内存淘汰策略(Eviction Policies)是指当 Redis 实例的内存使用达到配置的最大上限时,采取的一系列措施来删除现有的键,以腾出空间给新的数据。
以下是 Redis 内存淘汰策略的详细说明:
删除策略
1.volatile-lru(使用 LRU 算法删除设置了过期时间的键)
- 描述:从设置了过期时间的键中,使用 LRU(Least Recently Used,最近最少使用)算法删除最不常用的键。
- 应用场景:适用于需要在有过期时间的键中保持最常用的数据的情况。
2.allkeys-lru(使用 LRU 算法删除所有键)
- 描述:从所有键中,使用 LRU 算法删除最不常用的键。
- 应用场景:适用于希望在所有数据中保持最常用的数据的情况,而不考虑键是否设置了过期时间。
3.volatile-random(随机删除设置了过期时间的键)
- 描述:从设置了过期时间的键中,随机删除键。
- 应用场景:适用于希望简单地随机删除有过期时间的键,以释放内存的情况。
4.allkeys-random(随机删除所有键)
- 描述:从所有键中,随机删除键。
- 应用场景:适用于希望简单地随机删除键,以释放内存的情况。
5.volatile-ttl(删除设置了过期时间且剩余存活时间最短的键)
- 描述:从设置了过期时间的键中,删除剩余存活时间(TTL,Time to Live)最短的键。
- 应用场景:适用于希望首先删除那些即将过期的键,以尽量保留长时间有效数据的情况。
6.noeviction(不删除任何键)
- 描述:当内存使用达到上限时,不删除任何键,直接返回错误。
- 应用场景:适用于希望严格控制内存使用,不希望自动删除任何键的情况。通常用于希望 Redis 只作为缓存或持久存储的一部分,并在达到内存上限时明确地处理错误。
具体操作步骤
以下是 Redis 内存淘汰策略的具体操作步骤:
- 达到内存上限:
Redis 实例的内存使用达到配置的最大上限(由配置参数 maxmemory 设置)。
- 选择淘汰策略:
Redis 根据配置的淘汰策略(由 maxmemory-policy 参数设置)来决定如何释放内存。
- 执行淘汰策略:
根据选定的策略,Redis 选择要删除的键:
LRU 算法:Redis 使用近似 LRU 算法,维护一个候选键列表,并删除最不常用的键。
随机删除:Redis 从符合条件的键中随机选择并删除。
TTL 最短:Redis 删除剩余存活时间最短的键。
无淘汰:Redis 不删除键,直接返回错误(如 OOM command not allowed)。
- 释放内存:
删除选中的键,释放内存。
- 继续处理请求:
如果删除的键足以腾出足够的空间,Redis 继续处理客户端请求;否则,重复执行淘汰策略,直到满足内存要求或返回错误。
示例
假设 Redis 配置了 maxmemory 为 100MB,maxmemory-policy 为 allkeys-lru,当前内存使用已达到 100MB:
- 客户端发送 SET mykey value:
Redis 接收到 SET mykey value 请求。
- 检测内存使用:
Redis 发现内存使用已达上限,触发淘汰策略。
- 选择淘汰策略 allkeys-lru:
Redis 使用 LRU 算法,从所有键中选择最不常用的键。
- 删除最不常用的键:
Redis 删除 LRU 列表中的最不常用键,如 oldkey1 和 oldkey2。
- 释放内存并处理请求:
删除键后释放足够内存,Redis 继续处理 SET mykey value 请求,并成功存储新键 mykey。
4. 三种策略相互配合
配合工作
- 正常情况下:
定期删除 和 惰性删除 是主要的过期数据清理手段。
定期删除在后台自动清理一部分过期键,减少内存占用。
惰性删除确保每次访问时,过期键都能被及时清理,保证数据的有效性。
- 内存压力增大时:
当内存使用达到配置的最大上限时,触发 内存淘汰策略。
内存淘汰策略根据配置的策略(如 LRU、随机删除等)选择并删除部分键,以释放内存。
在这种情况下,定期删除和惰性删除继续工作,但主要任务是由内存淘汰策略来完成。
- 高效配合:
定期删除和惰性删除保证大部分过期键能够在不影响系统性能的情况下被清理。
内存淘汰策略则在内存压力过大时提供额外的保护,确保系统不会因为内存不足而出现问题。
这种多层次的内存管理机制,保证了 Redis 的高效和稳定运行。
示例场景
假设 Redis 实例设置了 maxmemory 为 100MB,淘汰策略为 allkeys-lru:
- 系统正常运行:
定期删除任务每 100 毫秒运行一次,随机检查一些设置了过期时间的键,删除过期键。
客户端访问键时,惰性删除机制检查键是否过期,过期键立即删除。
- 内存使用达到 90MB:
定期删除和惰性删除继续工作,但由于某些键没有被及时访问或定期任务未覆盖,内存使用仍在增长。
- 内存使用达到 100MB:
触发内存淘汰策略 allkeys-lru,Redis 删除最近最少使用的键,释放内存。
继续接受并处理新的客户端请求,确保系统正常运行。
相关推荐
- 使用 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分布式框架&分布式事务&分布式锁
-
总结本文承接上一篇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使编码配置...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)