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客户端重连指南。

相关文章
|
12天前
|
数据采集 人工智能 安全
|
7天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:七十、小树成林,聚沙成塔:随机森林与大模型的协同进化
随机森林是一种基于决策树的集成学习算法,通过构建多棵决策树并结合它们的预测结果来提高准确性和稳定性。其核心思想包括两个随机性:Bootstrap采样(每棵树使用不同的训练子集)和特征随机选择(每棵树分裂时只考虑部分特征)。这种方法能有效处理大规模高维数据,避免过拟合,并评估特征重要性。随机森林的超参数如树的数量、最大深度等可通过网格搜索优化。该算法兼具强大预测能力和工程化优势,是机器学习中的常用基础模型。
344 164
|
6天前
|
机器学习/深度学习 自然语言处理 机器人
阿里云百炼大模型赋能|打造企业级电话智能体与智能呼叫中心完整方案
畅信达基于阿里云百炼大模型推出MVB2000V5智能呼叫中心方案,融合LLM与MRCP+WebSocket技术,实现语音识别率超95%、低延迟交互。通过电话智能体与座席助手协同,自动化处理80%咨询,降本增效显著,适配金融、电商、医疗等多行业场景。
345 155
|
7天前
|
编解码 人工智能 自然语言处理
⚽阿里云百炼通义万相 2.6 视频生成玩法手册
通义万相Wan 2.6是全球首个支持角色扮演的AI视频生成模型,可基于参考视频形象与音色生成多角色合拍、多镜头叙事的15秒长视频,实现声画同步、智能分镜,适用于影视创作、营销展示等场景。
575 4
|
15天前
|
SQL 自然语言处理 调度
Agent Skills 的一次工程实践
**本文采用 Agent Skills 实现整体智能体**,开发框架采用 AgentScope,模型使用 **qwen3-max**。Agent Skills 是 Anthropic 新推出的一种有别于mcp server的一种开发方式,用于为 AI **引入可共享的专业技能**。经验封装到**可发现、可复用的能力单元**中,每个技能以文件夹形式存在,包含特定任务的指导性说明(SKILL.md 文件)、脚本代码和资源等 。大模型可以根据需要动态加载这些技能,从而扩展自身的功能。目前不少国内外的一些框架也开始支持此种的开发方式,详细介绍如下。
1013 7