Redis key 消失之谜

news/2025/10/30 10:50:27/文章来源:https://www.cnblogs.com/vivotech/p/19176212

作者:vivo 互联网存储团队 - Lin Haiwen、Xu Xingbao

本文从一次生产环境业务服务报错,逐步对问题进行定位,深入分析之后发现导致问题的原因,给出相应的优化方法,提升业务可用性。

 

1分钟看图掌握核心观点👇

图片

一、问题描述

1.1 报错信息

应用服务报错,通过监控日志发现凌晨2点的时候,应用报错获取不到Redis key。

 

1.2 告警与监控信息

首先想到是否由于内存满导致的key淘汰,生产的所有Redis都有设置内存告警,但没有收到内存告警信息;(内存告警需要每隔10秒,连续3次触发才会告警。)

从监控图中,可以看到Redis内存稍有增长,但使用率一直偏低,并没有达到使用率告警。

图片

查看监控信息:在问题时间点,发生了大量的key过期,初步怀疑是由于key批量设置了过期时间,正好到期了导致大量key失效。

图片

查看Redis错误日志,没有发现异常。

 

二、问题定位

  • 基于前面的监控,初步怀疑是key设置了过期时间导致失效。

  • 是否有上线其他新功能导致?

 

但是业务反馈不是由于设置过期时间导致;并且第二天问题复现,因此继续深入定位。

2.1 key是否过期

  • 查看淘汰策略

  • 查看key过期时间

 

初步判断确实不是因为key过期导致的大量淘汰,这里TTL接近5天,但是连着2天出现问题,因此不应该是过期时间到了导致。

xxx:xxx> config get'maxmemory-policy'
1)"maxmemory-policy"
2)"volatile-lru"
xxx:xxx> ttl finance:xxxx_cms_version_10000
-> Redirected to slot [9229] located at xxx:xxx
(integer)387585
xxx:xxx> ttl finance:xxxcms_basic_data_10423
(integer)387574

key是被删除还是淘汰?查看监控,发现存在key确实被淘汰,说明接下来需要考虑内存问题。

图片

 

2.2 是否内存满了

发现确实短时间内存写满了,一开始查看监控由于时间拉的比较长,查看增长趋势没发现内存写满情况,但是由于没有达到告警条件,没有满足连着3次触发阈值,故没有触发告警。

同时内存用满问题持续时间较短,约10分钟左右。

图片

 

其他指标检查,发现出现问题时client_longest_output_list指标存在明显突刺,该指标非常可疑。

图片

 

请求量的大涨,怀疑是请求堆积导致buffer增长使得内存写满。但是此时还有疑点:写入也上涨,是否是由于读请求积压导致,还是因为写入数据导致内存满?

2.3 找出内存涨的来源

设置定时任务,对出问题时间点前后20分钟这段时间进行抓包分析。

对比出问题前后几分钟的请求,对应时间点请求量飙升,并且请求量来源基本是get请求,set请求也少量增长。

4860 get finance:xxxx__10122
4925 get finance:xxxx__10032
4945set finance:xxxx_data_10013-0
4947 get finance:xxxx_data_10013_cms_version_10000
4976 get finance:xxxx__10251
5054set finance:xxxx__undefined
5098 get finance:xxxx__10018
8729 get finance:xxxx_data_10415_cms_version_10000
9152 get finance:xxxx_data_10401_cms_version_10000
9553 get finance:xxxx_data_10228_cms_version_10000
9597 get finance:xxxx_data_10213_cms_version_10000
9622 get finance:xxxx_data_10032_cms_version_10000
9647 get finance:xxxx_data_10347_cms_version_10000
9674 get finance:xxxx_data_10182_cms_version_10000
9742 get finance:xxxx_data_10251_cms_version_10000
10085 get finance:xxxx_data_10019_cms_version_10000
23064 get finance:xxxx__10423
45176 get finance:xxxx_data_10423_cms_version_10000 [root@db-prd-xxx.v-bj-3.vivo.lan:/data/redis/scpdir]# cat 0807.cap | grep '2024-08-07 01:59'|awk '{print $8,$10}'|sort |uniq -c |sort -k 1 -n

 

同时也对set的内容进行分析,发现set的数据并不足使内存写满;且上面监控可以看到,内存写满问题持续时间很短,因此应该不是数据增长导致。

进一步对get请求来源分析:

 

结合 IP来源以及 keyname;跟业务同学沟通确认:

由于业务读请求量大涨导致,业务请求从每分钟27w左右上涨到70w左右,主要有:

2.4 机制分析

内存用量上涨超限会触发Redis节点基于已经配置的volatile-lru策略进行过期数据淘汰,所以需要找到内存上涨的来源。基于监控指标排查分析,基本确定了发生异常期间没有集中的大量数据写入,反而发现大量网络数据的输出,抓包也印证了此时节点主要是在处理get命令读请求。进一步地发现了client-output-buffer-limit这个指标出现异常上涨,才最终锁定到Redis的回包积压问题。

 

关于Redis的结果回包逻辑,首先要了解Redis的结果存储空间设计。Redis针对每一个连接客户端都会初始化一个大小为16K的静态的buf区域和一个空的链表结果,相关声明代码如下:

#define REDIS_REPLY_CHUNK_BYTES (16*1024) /* 16k output buffer */
char buf[REDIS_REPLY_CHUNK_BYTES];
list *reply;
c->reply = listCreate();

 

对于Redis而言正常执行的命令都会有数据回包,而回包结果都需要在客户端中做暂存。Redis是如何结合以上两个数据进行结果存储的呢?主要逻辑是如果静态buf区域能够满足回包结果存储,即结果不大于16k,那么结果就会存储静态buf中,将结果不断插入reply链表中;同时我们都知道Redis支持丰富的数据类型和操作命令,有些批量数据读取命令的结果可能会有很多字段,这些字段也会作为一个个链表元素追加到reply链表中。正常情况下,我们在Redis节点上执行info clients命令可以获得如下客户端的统计信息:

 > info clients 
 # Clients 
 connected_clients:  1
 client_longest_output_list:  0
 client_biggest_input_buf:  0
 blocked_clients:  

其中的client_longest_output_list字段代表此时节点的所有连接客户端中回包结果的缓存情况。

 

但是按照之前服务监控和抓包结果分析,具体执行的指令都是get,实际数据也没有超过16k大小,并没有满足将结果存储到链表的条件。这里有个经常被忽略的场景,就是Redis其实支持pipeline命令执行方式的,简单来说就是Redis支持一次性接收一个客户端的多个指令,具体执行过程中会把这些指令的结果不断暂存,然后在后续流程中集中回包,如果这时候不能及时地把数据通过网络发出去,就有可能出现reply链表长度激增的现象,进而导致客户端占用内存激增,这正是我们本次遇到的场景。

图片

 

Redis的maxmemory参数限制的是Redis实例可以使用的最大内存,这部分内存主要包括以下几个部分:业务数据占用的内存、客户端连接的输入/输出缓冲区、复制积压缓冲区、AOF 缓冲区以及其他一些内部开销。

 

具体来说,Redis 的maxmemory 限制包括:

  1. 业务数据占用的内存,这部分是用户在Redis中存储的数据。

  2. 客户端连接的输入/输出缓冲区,用于暂存客户端发送的命令和Redis 返回给客户端的数据。

  3. 复制积压缓冲区:用于主从复制,当从节点断线重连时,可以从这个缓冲区拉取丢失的数据。

  4. AOF 缓冲区:用于持久化,当开启AOF 持久化时,Redis 会将写操作追加到AOF 缓冲区,然后异步地写入AOF 文件。

  5. 其他内部开销:包括Redis 进程本身的一些数据结构、对象、碎片内存等。

 

因此,在设置Redis 的maxmemory 参数时,需要综合考虑业务数据的内存占用、各个缓冲区的大小以及内存碎片率等因素,合理地分配内存,避免出现内存溢出或性能下降的问题。

 

三、问题解决

3.1 紧急修复

  • 临时扩大Redis集群内存,避免内存写满。

  • 限制client-output-buffer-limit大小,避免由于请求过大导致内存突增。

  • 业务限流&削峰,避免请求量突增。

  • 增加兜底机制,如果由于Redis key被淘汰,则去MySQL查询,避免业务直接报错。

 

3.2 根本解决

业务进行业务逻辑优化,将请求打散,避免同一时间集中大量请求Redis。

 

四、总结

本次问题是由于业务集中请求Redis,导致缓存积压内存增长达到最大内存限制,触发Redis淘汰策略对key进行驱逐。key被淘汰丢失后,需要增加兜底机制去DB侧请求避免业务报错。虽然Redis性能比较好,但是也要尽量打散请求,合理评估存储侧的性能。

 

同时,对于Redis淘汰策略,对于数据比较重要的集群,可以考虑使用不驱逐的方式。合理设置TTL保留时间,把Redis的内存使用率保持在安全的区域。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/950575.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Blazor 感觉回到了ASP时代?

大家好,我是码农刚子。前几天分享的文章:《ASP.NET Core Blazor简介和快速入门三(布局和路由)》下面,有朋友评论说:这blazor 感觉回到了asp 时代。回想一下ASP时代是什么时候,大家还有没有印象。我2019年出来工…

2025年靠谱的FFU龙骨优质厂家推荐榜单

2025年靠谱的FFU龙骨优质厂家推荐榜单 在洁净室、电子制造、医疗等高端领域,FFU(风机过滤单元)龙骨作为核心支撑结构,其质量直接影响空气净化系统的稳定性和使用寿命。选择一家技术成熟、产能稳定、售后服务完善的…

2025年比较好的三维调节阻尼托底轨TOP品牌厂家排行榜

2025年比较好的三维调节阻尼托底轨TOP品牌厂家排行榜 随着家具行业对功能性与品质要求的不断提升,三维调节阻尼托底轨作为高端抽屉系统的核心部件,其市场需求持续增长。优质的托底轨不仅能实现静音开合、缓冲防夹,…

父子组件联动出现问题的一个bug记录

父子组件联动出现问题的一个bug记录这是Bug是这样,父组件有个部门的树,子组件有个饼图。 初始状态下,部门树默认是查询全部部门,饼图是有数据的,切换不同的部门后,饼图也是有数据的。 但是当部门切回全部时候,饼…

ArkTS语言入门:HarmonyOS应用开发的新基石

ArkTS是HarmonyOS应用开发的推荐语言,它基于TypeScript,并扩展了声明式UI语法。本文将带你全面了解ArkTS语言的基础语法和核心特性,为HarmonyOS应用开发打下坚实基础。一、ArkTS与TypeScript的关系 ArkTS是TypeScri…

大模型越来越多,国产AI的突围之路在哪里?

一、大模型“遍地开花”,同质化的隐忧 过去两年,全球AI行业进入了「大模型百花齐放」时代。OpenAI的GPT系列、Anthropic的Claude、Google的Gemini、Mistral的开源路线……国外大厂纷纷亮剑。与此同时,中国的大模型数…

2025年靠谱的卫浴缓冲隐藏轨厂家最新权威实力榜

2025年靠谱的卫浴缓冲隐藏轨厂家最新权威实力榜在卫浴五金行业,缓冲隐藏轨作为高端橱柜、浴室柜的核心配件,其品质直接影响产品的使用寿命和用户体验。随着消费者对家居品质要求的提升,具备静音、缓冲、承重强等特点…

【2025-10-29】买了周卡

20:00人谁不顾老,老去有谁怜。身瘦带频减,发稀冠自偏。废书缘惜眼,多灸为随年。经事还谙事,阅人如阅川。细思皆幸矣,下此便偷然。莫道桑榆晚,为霞尚满天。——《酬乐天咏老见示》 唐刘禹锡今天又是焦头烂耳的一天…

鸿蒙初开:HarmonyOS 5应用开发环境搭建(DevEco Studio)全指南

鸿蒙初开:HarmonyOS 5应用开发环境搭建(DevEco Studio)全指南 本文将手把手带你完成HarmonyOS 5应用开发的第一步,也是最关键的一步——开发环境的搭建。我们将从系统要求开始,直至在模拟器上成功运行第一个“Hel…

AI智能客服机器人是怎么做出来的?

AI智能客服机器人是怎么做出来的?大家好!今天咱们来聊聊AI智能客服机器人到底是怎么做出来的。如果你好奇这些能7*24小时在线、秒回问题的“数字员工”是如何工作的,或者正考虑为企业搭建一套智能客服系统,这篇文章…

2025年方形真空干燥机工厂权威推荐榜单:圆形真空干燥机/真空干燥机/双锥回转真空干燥机源头厂家精选

在化工、制药等行业的生产线上,一台高效的方形真空干燥机正将一批热敏性物料的含水率精准降至0.5%以下,而能耗较传统设备降低了30%以上。 方形真空干燥机作为现代工业干燥技术的重要组成部分,以其空间利用率高、易于…

2025年深度解析珠海爱尔眼科医院:专业资源配置与区域服务能力评估

本文将从医院规模与硬件配置的维度出发,为读者提供一个有针对性的客观参考。珠海爱尔眼科医院作为粤港澳大湾区重要的专业眼科医疗机构,其基础设施与设备投入直接关系到区域眼健康服务的可及性与质量。随着眼科疾病谱…

2025年10月成都考公培训机构推荐榜单:五大机构综合对比分析

对于许多在成都备考公务员或事业单位的考生来说,选择一家合适的培训机构是提升备考效率的关键一步。无论是应届毕业生缺乏考试经验,还是往届生希望实现职业转型,都期望通过专业指导增强竞争力。当前成都考公培训市场…

2025年10月成都考公培训机构评价报告:多维数据与用户反馈解析

随着公务员和事业单位考试竞争日益激烈,选择一家可靠的培训机构成为许多考生备考过程中的关键环节。对于在成都备考的考生而言,无论是应届毕业生缺乏应试经验,还是往届生寻求职业转型,都需要专业指导来提升竞争力。…

搭建gitea私人服务器

gitlab太大了~~功能虽然多,但是小公司不一定用得到,这时候gitea的好处就展示出来了 二进制下载地址 https://github.com/go-gitea/gitea/releases/ 下载对应的版本的二进制,然后直接启动。正式环境记得配置守护进程…

Kafka关闭日志,启动一直打印日志

前言 本地调试过程中,Kafka一直打印日志,又不好直接关闭,所以寻求关闭日志输出方法 解决 og4j.properties文件追加一句 #设置kafka日志输出级别log4j.logger.org.apache.kafka=ERROR

[Paper Reading] UniME-V2: MLLM-as-a-Judge for Universal Multimodal Embedding Learning

目录UniME-V2: MLLM-as-a-Judge for Universal Multimodal Embedding LearningTL;DRMethodMLLM-as-a-Judge for Hard Negatives MiningMLLM Judgment Based Training FrameworkQ&A (从上面可以找到答案)Experiment…

2025年耐用的轻集料混凝土最新TOP厂家排名

2025年耐用的轻集料混凝土最新TOP厂家排名 随着建筑行业对环保、轻质、高强度材料需求的增长,轻集料混凝土因其优异的性能(如减轻结构自重、提高抗震性、改善保温隔热效果)成为市场热点。2025年,国内轻集料混凝土…

2025 年西安买房住宅最新推荐榜,聚焦企业开发实力与居住价值深度解析陕西买房/沣东买房/刚需买房推荐

引言 2025 年西安楼市分化加剧,城北作为热门置业板块,楼盘品质差异显著。为破解购房者选房难题,本次榜单依托中指研究院《2025 年西安住宅产品力测评报告》及克而瑞陕西区域数据,采用三维测评体系:企业实力维度占…