Redis为什么会发生频繁的驱逐操作_优化业务逻辑降低大容量Value的写入频次

梦浩吖_1985

梦浩吖_1985

2026-04-14

803人浏览

原创

redis驱逐频繁主因是maxmemory过小或value过大,表现为evicted_keys激增、used_memory_peak逼近maxmemory;应通过--bigkeys定位大key、压缩/拆分value、校验去重写入,并监控evicted_keys增速与used_memory_dataset_perc是否收敛。

redis为什么会发生频繁的驱逐操作_优化业务逻辑降低大容量value的写入频次

Redis 驱逐频繁,大概率是 maxmemory 设置过小或 Value 过大

Redis 启动时若配置了 maxmemory(比如 2GB),而业务持续写入大 Value(如序列化后的用户画像、HTML 片段、Base64 图片),内存很快触顶,就会触发 maxmemory-policy 定义的驱逐策略(如 allkeys-lru)。这不是“缓存淘汰正常现象”,而是内存压力已失控的信号——尤其当 evicted_keys 指标每秒增长数十次,同时 used_memory_peak 接近 maxmemory,基本可断定是 Value 尺寸和写入频次共同导致的恶性循环。

实操建议:

Redis Skill - 高性能缓存管理
Redis Skill - 高性能缓存管理

Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。

下载
  • 用 redis-cli --stat 实时观察 evicted_keys 和 used_memory_human 变化节奏,确认是否集中在某类 key 上
  • 通过 redis-cli --bigkeys 扫描,定位 >1MB 的 key;注意它只采样,需配合 MEMORY USAGE <key></key> 精确验证
  • 检查业务日志中是否在高频调用 SET 或 HSET 写入含大量字段的 Hash(例如一次写入 500 个用户标签)

大 Value 写入本身会放大内存开销与阻塞风险

一个 5MB 的字符串 Value,在 Redis 中实际占用不止 5MB:RDB/AOF 持久化时需完整拷贝;主从同步时整块传输;如果启用了 lazyfree-lazy-eviction yes,驱逐时虽不阻塞主线程,但后台线程释放内存仍需时间。更隐蔽的问题是,大 Value 会让 INFO memory 中的 mem_fragmentation_ratio 异常升高(>1.5),说明内存碎片严重,进一步加剧驱逐频率。

实操建议:

  • 禁止直接存 Base64 图片、JSON 数组(>100KB)、未压缩的 HTML —— 这些应转存对象存储,Redis 只存 URL 或 ID
  • Hash 类型慎用 HSET key field value 单字段写入大内容;改用分片:按业务维度拆成 user:123:profile:part1、user:123:profile:part2
  • 对必须缓存的大结构(如推荐列表),先用 zstd 或 snappy 压缩再存,读取时解压;注意压缩/解压耗时是否可接受

降低写入频次的关键是识别并拦截无效/重复写入

很多驱逐风暴并非来自真实业务增长,而是代码缺陷:比如定时任务每 10 秒全量刷新用户缓存,即使用户数据没变也强制 SET;或接口幂等性缺失,前端重试导致同一份大 Value 被反复写入。这类写入既无业务价值,又直接消耗内存配额。

实操建议:

  • 在写入前加一层轻量比对:用 GET <key></key> 读旧值,MD5 或 crc32 校验新旧内容是否一致,仅不同时才 SET
  • 对定时刷新场景,改用「变更驱动」:监听数据库 binlog 或消息队列,只在数据真正更新时触发缓存更新
  • 给高频写入 key 加监控告警,例如用 MONITOR 抓包分析 5 分钟内 SET user:* 的调用来源,定位 SDK 或中间件的滥用行为

业务逻辑改造后必须验证驱逐是否真正收敛

改完代码、调大 maxmemory 或加压缩,不代表问题解决。要盯住两个指标:一是 evicted_keys 增速是否归零或降至个位数/分钟;二是 used_memory_dataset_perc(实际数据占比)是否稳定在 70%–85%,长期低于 60% 说明仍有冗余或冷数据未清理。

容易被忽略的点:

  • maxmemory-policy 设为 noeviction 不是解法——它会让写入直接报错 (error) OOM command not allowed when used memory > 'maxmemory'.,业务更不可控
  • 集群模式下,单个 slot 的大 Value 会导致该节点内存独占飙升,其他节点空闲,此时横向扩容无效,必须先做 Value 拆分
  • 客户端 SDK(如 Jedis/Lettuce)若开启 pool 且 maxTotal 过小,可能因连接等待间接拉长写入耗时,掩盖真实瓶颈

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

redis

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

2024.05.11

609

5

Golang 中间件开发与微服务架构
Golang 中间件开发与微服务架构

本专题系统讲解 Golang 在微服务架构中的中间件开发,包括日志处理、限流与熔断、认证与授权、服务监控、API 网关设计等常见中间件功能的实现。通过实战项目,帮助开发者理解如何使用 Go 编写高效、可扩展的中间件组件,并在微服务环境中进行灵活部署与管理。

2025.12.18

604

18

ThinkPHP中间件机制与请求拦截处理实践
ThinkPHP中间件机制与请求拦截处理实践

本专题围绕 ThinkPHP 中间件体系展开,深入讲解中间件的定义、注册与执行流程。内容包括全局中间件与路由中间件的区别、请求前后处理逻辑、自定义中间件开发以及权限验证与日志处理应用。通过实际案例,帮助开发者掌握中间件在项目中的核心作用与最佳实践。

2026.03.31

418

17

json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2023.08.07

2035

5

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.23

2962

1

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

2023.10.13

1016

3

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

2025.09.10

3359

7

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.18

949

5

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.25

2660

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpEnv手册
phpEnv手册

共0课时 | 0人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.5万人学习