Redis:内存陡增100%深度复盘

简介: 本文分析了Redis在11:22:02因缓冲区激增导致不可用的事故。根源在于流出带宽自然增长至96MB/s,触发输出缓冲区暴涨,连接断开后请求涌向DB,大量大KEY写入又引发输入缓冲区激增,最终占用全部内存,阻塞主线程。事故暴露了网络与存储资源双重瓶颈,凸显遵循开发运维规范的重要性,如合理设计Key、控制命令使用、优化SDK配置等,以避免性能边界被突破。

分析:为何缓冲区激增(Redis不可用的时间点11:22:02,之前都发生了什么)
知道了缓冲区挤爆Redis内存会导致Redis不工作之后,接下来就是分析为何当时出现了缓冲区激增并最终导致redis不可用。
实例信息

相关代码

案件还原
1.自然增长导致流出带宽不断变大直至96MB/s。

2.流出带宽超过96MB/s,输出缓冲区内存占用激增甚至溢出 (300setMaxTotal*10机器ip数量个客户端,之前推导过可以到9G)。

3.导致输出缓冲区爆了,redis客户端连接不得不关闭。
4.客户端连接关闭后,导致请求都走DB。
5.DB走完之后都会执行SET。
6.SET流量飙升,且因都是大KEY,导致流入带宽激增(别看写QPS只有50,但是如果每个写都是2MB,就可以做到瞬间占满流入带宽)。

7.Redis主线程模型,处理请求的速度过慢(大KEY),出现了间歇性阻塞,无法及时处理正常发送的请求,导致客户端发送的请求在输入缓冲区越积越多。
8.输入缓冲区内存随即激增。

9.最终,redis内存被缓冲区内存(输入、输出)完全侵占。
10.后续的SET GET命令甚至都进不了输入缓冲区,阻塞持续到客户端配置的SoTimeout时间;但是流入流出带宽依然占据并持续,总带宽到达了216MB/s > 实例最大带宽192MB/s。

11.造成最终的不可用(后续的命令想进场,要依赖当前输入缓冲区里的命令被执行给你腾出来位置,但是还是那句话Redis主线程处理消化的速度,实在是太慢了;从图中,可以看到Redis的QPS骤降。

11:35分之后,我把redis降级了,全使用db来抗流量。

开发运维规范
可以看到Redis的性能是有边界的,不能盲目相信所谓的高性能。
真正理解性能须使用benchmark。

它也是有问题能造成他的性能瓶颈的。

计算资源 使用通配符、Lua并发、1对多的PUBSUB、热点Key等会大量消耗计算资源,集群架构下还会导致访问倾斜,无法有效利用所有数据分片。
存储资源 Streaming慢消费、大Key等会占用大量存储资源,集群架构下还会导致数据倾斜,无法有效利用所有数据分片。
网络资源 扫描全库(KEYS命令)、大Value、大Key的范围查询(如HGETALL命令)等会消耗大量的网络资源,且极易引发线程阻塞。
重要
Redis的高并发能力不等同于高吞吐能力,例如将大Value存在Redis里以期望提升访问性能,此类场景往往不会有特别大的收益,反而会影响Redis整体的服务能力。
在上述的事故中,就占了【网络资源消耗高】【存储资源消耗高】两大问题
因此也到了本文的方法论环节:从业务部署、Key的设计、SDK、命令、运维管理等维度展示云数据库Redis开发运维规范:
● 业务部署规范:https://help.aliyun.com/zh/redis/use-cases/development-and-o-and-m-standards-for-apsaradb-for-redis
● Key设计规范:https://help.aliyun.com/zh/redis/use-cases/development-and-o-and-m-standards-for-apsaradb-for-redis
● SDK使用规范:https://help.aliyun.com/zh/redis/use-cases/development-and-o-and-m-standards-for-apsaradb-for-redis
● 命令使用规范:https://help.aliyun.com/zh/redis/use-cases/development-and-o-and-m-standards-for-apsaradb-for-redis
● 运维管理规范:https://help.aliyun.com/zh/redis/use-cases/development-and-o-and-m-standards-for-apsaradb-for-redis
业务部署规范
重要程度 规范 说明
★★★★★ 确定使用场景为高速缓存或内存数据库。 ● 高速缓存:建议关闭AOF以降低开销,同时,由于数据可能会被淘汰,业务设计上避免强依赖缓存中的数据。例如Redis被写满后,会触发数据淘汰策略以挪移出空间给新的数据写入,根据业务的写入量会相应地导致延迟升高。
重要
如需使用通过数据闪回按时间点恢复数据功能,AOF功能需保持开启状态。
● 内存数据库:应选购企业版(持久内存型),支持命令级持久化,同时应通过监控报警关注内存使用率。具体操作,请参见报警设置。
★★★★★ 就近部署业务,例如将业务部署在同一个专有网络VPC下的ECS实例中。 Redis具备极强的性能,如果部署位置过远(例如业务服务器与Redis实例通过公网连接),网络延迟将极大影响读写性能。
说明
针对多地部署应用的场景,您可以通过全球多活功能,借助其提供的跨域复制(Geo-replication)能力,快速实现数据异地灾备和多活,降低网络延迟和业务设计的复杂度。更多信息,请参见Redis全球多活简介。
★★★★☆ 为每个业务提供单独的Redis实例。 避免业务混用,尤其需要避免将同一Redis实例同时用作高速缓存和内存数据库业务。带来的影响例如针对某个业务淘汰策略设置、产生的慢请求或执行FLUSHDB命令影响将扩散至其他业务。
★★★★☆ 设置合理的过期淘汰策略。 云数据库Redis默认的默认逐出策略为 volatile-lru ,关于各逐出策略的说明,请参见Redis配置参数列表。
★★★☆☆ 合理控制压测的数据和压测时间。 云数据库Redis不会对您压测的数据执行自动删除操作,您需要自行控制压测数据的数据量和压测时间,避免对业务造成影响。
Key设计规范
重要程度 规范 说明
★★★★★ 设计合理的Key中Value的大小,推荐小于10 KB。 过大的Value会引发数据倾斜、热点Key、实例流量或CPU性能被占满等问题,应从设计源头上避免此类问题带来的影响。
★★★★★ 设计合理的Key名称与长度。 ● Key名称:
● 使用可读字符串作为Key名,如果使用Key名拼接库、表和字段名时,推荐使用英文冒号(:)分隔。例如project:user:001。
● 在能完整描述业务的前提下,尽量简化Key名的长度,例如username可简化为u。
● 由于大括号({})为Redis的hash tag语义,如果使用的是集群架构的实例,Key名称需要正确地使用大括号避免 引发数据倾斜 ,更多信息,请参见keys-hash-tags。
说明
集群架构下执行同时操作多个Key的命令时(例如RENAME命令),如果被操作的Key未使用hash tag让其处于相同的数据分片,则命令无法正常执行。
● 长度:推荐Key名的长度不超过128字节(越短越好)。
★★★★★ 对于支持子Key的复杂数据结构,应避免一个Key中包含过多的子Key(推荐低于1,000)。
说明
常见的复杂数据结构例如Hash、Set、Zset、Geo、Stream及Tair(Redis企业版)特有的exHash、Bloom、TairGIS等。 由于某些命令(例如HGETALL)的时间复杂度直接与Key中的子Key数量相关。如果频繁执行时间复杂度为O(N)及以上的命令,且Key中的子Key数量过多容易引发慢请求、数据倾斜或热点Key问题。
★★★★☆ 推荐使用串行化方法将Value转变为可读的结构。 由于编程语言的字节码随着版本可能会变化,如果存储裸对象(例如Java Object、C#对象)会导致整个软件栈升级困难,推荐使用串行化方法将Value变成可读的结构。
SDK使用规范
重要程度 规范 说明
★★★★★ 推荐使用JedisPool或者JedisCluster连接实例。
说明
企业版(内存型)实例推荐使用TairJedis客户端,支持新数据结构的封装类。使用方法,请参见通过客户端程序连接Redis。 如果使用单连接的方式,一旦遇到单次超时则无法自动恢复。关于JedisPool的连接方法,请参见通过客户端程序连接Redis、JedisPool资源池优化和JedisCluster。
★★★★☆ 程序客户端需要对超时和慢请求做容错处理。 由于Redis服务可能因网络波动或资源占满引发超时或慢请求,您需要在程序客户端上设计合理的容错机制。
★★★★☆ 程序客户端应设置相对宽松的超时重试时间。 如果超时重试时间设置的非常短(例如200毫秒以下),可能引发重试风暴,极易引发业务层雪崩。更多信息,请参见Redis客户端重连指南。

相关文章
|
11月前
|
SQL 缓存 监控
MySQL缓存机制:查询缓存与缓冲池优化
MySQL缓存机制是提升数据库性能的关键。本文深入解析了MySQL的缓存体系,包括已弃用的查询缓存和核心的InnoDB缓冲池,帮助理解缓存优化原理。通过合理配置,可显著提升数据库性能,甚至达到10倍以上的效果。
|
SQL 存储 监控
功能解读|快速上手 OceanBase 数据迁移服务
在上一期的 OceanBase 功能解读系列文章中,我们为大家带来了 ODC 功能解读(戳这里回顾:《OceanBase 开发者中心 ODC 功能解读》),本文将为大家分享数据迁移服务的相关内容。
1442 0
功能解读|快速上手 OceanBase 数据迁移服务
|
7月前
|
关系型数据库 MySQL Java
Java微服务连接同个MySQL实例报错“Too many connections”
多个微服务共享同一MySQL实例时,易因连接池配置不当导致“Too many connections”错误。需综合评估max_connections限制与各服务连接池大小,合理调整数据库配置与应用参数,避免连接耗尽。
235 6
|
8月前
|
存储 人工智能 搜索推荐
向量数据库的基本概念
向量数据库是专为存储和检索高维向量设计的系统,能将图片、文本等非结构化数据转化为“数字指纹”(向量),通过相似性搜索快速找到相近内容,广泛应用于推荐系统、图像识别和AI搜索等领域。
|
8月前
|
消息中间件 人工智能 NoSQL
RocketMQ:A2A协议实现多智能体优化
Apache RocketMQ 推出轻量级通信模型 LiteTopic,专为 AI 多智能体协作设计,支持海量会话、上下文持久化与断点续传。结合 A2A 协议与阿里 AgentScope 框架,实现高可靠、低延迟的智能体通信,助力企业构建稳定高效的多智能体应用。
|
8月前
|
机器学习/深度学习 人工智能 自然语言处理
大模型专业名词解释手册
本手册由油炸小波设计提示词,Manus创作,系统梳理大语言模型核心概念,涵盖基础架构、训练方法、优化技术、应用推理及伦理评估。内容详实,术语权威,助力深入理解AI大模型世界。
|
8月前
|
人工智能 JSON 数据挖掘
全面认识MCP:大模型连接真实世界的“USB-C接口”
MCP通过动态上下文窗口、多步骤流程支持与标准化通信协议,实现AI智能体对用户偏好、会话历史与环境数据的持续记忆与灵活响应。其基于JSON-RPC 2.0的统一接口,支持Stdio、HTTP/SSE等传输方式,简化了大模型与工具系统的集成。借助MCP,AI应用可高效完成数据分析、办公自动化等复杂任务,提升处理能力的同时保障安全合规,推动大模型在真实场景中的落地应用。
|
8月前
|
存储 机器学习/深度学习 人工智能
向量数据库的工作原理
向量数据库通过将非结构化数据转化为高维向量嵌入,利用HNSW、IVF-PQ等索引技术实现高效相似性搜索。其采用列式存储、量化压缩与分布式架构,优化高维向量的存储与检索,支持AI场景下的大规模近似最近邻查询,显著提升搜索效率与可扩展性。
|
8月前
|
XML 算法 安全
详解RAG五种分块策略,技术原理、优劣对比与场景选型之道
RAG通过检索与生成结合,突破大模型在企业应用中的局限,支持知识动态更新、降低幻觉风险。分块策略是其核心,直接影响检索效率与答案准确性。本文系统解析固定大小、语义、递归、结构化及LLM-based五种分块方法,对比优劣,提出选择建议,并探讨RAG在高风险领域的可验证性挑战与前沿优化方向。
|
8月前
|
人工智能 JSON 数据挖掘
大模型应用开发中MCP与Function Call的关系与区别
MCP是模型与外部系统交互的通用协议,实现多模型兼容的标准化通信;Function Call则是模型调用外部工具的具体机制。前者为“桥梁”,后者为“工具”,二者协同拓展大模型能力边界,提升应用灵活性与智能化水平。

热门文章

最新文章