真·Redis缓存优化—97%的优化率你见过嘛? | 京东云技术团队

news2024/11/19 0:39:19

本文通过一封618前的R2M(公司内部缓存组件,可以认为等同于Redis)告警,由浅入深的分析了该告警的直接原因与根本原因,并根据原因提出相应的解决方法,希望能够给大家在排查类似问题时提供相应的思路。

一、问题排查

1.1 邮件告警

正值618值班前夕,某天收到了邮件告警,告警内容如下:

您好,R2M监控报警,请您及时追踪一下! 报警信息:告警ID:6825899, 应用:zr_credit_portal, 负责人:zhangsan, 告警类型:内存使用率, 时间:2023-06-15 16:00:04。实例:(10.0.0.0:5011-slave), 当前:9212MB 超过警戒值:8748MB 实例最大内存:10800 MB,内存使用率:85 % ;实例:(10.0.0.0:5023-master), 当前:9087MB 超过警戒值:8748MB 实例最大内存:10800 MB,内存使用率:84 % ;实例:(10.0.0.0:5017-master), 当前:9214MB 超过警戒值:8748MB 实例最大内存:10800 MB,内存使用率:85 % ;

大概内容是说,R2M集群使用率已经达到85%,需要紧急处理下。

我们的缓存集群配置如下,总共32400MB容量,三主三从,每个主节点10800M容量,目前使用最高的已经达到9087M。R2M使用集群模式进行部署。

image-20230713164727082

首先的思路就是使用大key统计,查看是哪些缓存占用了容量。因为大key统计是从节点进行扫描,所以不用担心会影响线上主流程。

image-20230713170916595

1.2 代码分析

大key主要分为两类,一类是xxx_data,一类是xxx_interfacecode_01,按照此规律去代码中寻找存放key的地方

String dataKey = task.getTaskNo() + "_data";
cacheClusterClient.setex(dataKey.getBytes(), EXPIRATION, DataUtil.objectToByte(paramList));

key = task.getTaskNo() + "_" + item.getInterfaceCode() + "_" + partCount;
cacheClusterClient.setex(key.getBytes(), EXPIRATION,DataUtil.objectToByte(dataList));


找到了代码位置后,分析其业务流程:

伏羲运营后台插入数据优化-第 3 页.drawio

1.3 告警原因

综合上图分析,此次占用率过高的原因可以分为直接原因与根本原因:

1.3.1 直接原因

查看运营后台确实发现有用户在此前三天创建了大量的跑批任务,导致缓存中样本与结果数量增加,从而导致缓存使用率过高。

1.3.2 根本原因

分析代码后,根据上文描述缓存中主要有两块数据:样本与结果

  • 首先是样本在缓存中存了一下随机又取出,本操作毫无意义,只会占用缓存容量。

  • 结果分批分片存储,此步骤有意义,主要是为了防止在多任务并行处理时,如果不将数据分片存入缓存,很有可能导致数据在JVM中占用大量空间,进而导致FULL GC的问题。(之前文章已分析)

  • 跑批结束后,中间数据正常来说已经无用,但是业务流程并没有主动删除无用数据,而是等待超时后自动删除,本操作会导致数据在缓存中额外存储较长时间。

至此,已经分析出了本次缓存使用率过高的原因(其实还没有,直接原因只分析出了表象,直接原因的“根本原因”还未有结论)。

二、问题解决

上文分析了本次告警的排查过程,以下是如何解决问题,也是分为如何解决直接原因与解决根本原因。

2.1 直接原因

2.1.1 原因分析

正值618前夕,最好不考虑操作会对系统产生的影响,因此只能先考虑让对应的用户暂时停止创建跑批,以免继续占用内存导致影响线上业务。

此时观察监控图又发现:
image.png

用户是从三天前就开始创建跑批任务的(对应缓存开始增长的时间点),但是缓存的有效期只有一天,按道理来说从第二天开始每天的缓存都应该下降不少才对(因为前一天的已经过期了),为什么看监控图这三天的缓存使用率近乎直线上升呢?

此处可以思考30s,与Redis特性有关。

根据之前刚系统的学完Redis的相关特性,关注到此问题点后,开始思考有没有可能是虽然我们设置了超时时间是一天,但是实际上数据并没有被物理删除呢(Redis的缓存淘汰策略)?

随后查看R2M相关文档:

image-20230907145129672

其中:

如果带有生存时间的键非常多的话, 那么在键的生存时间变为0, 直到键真正被删除这中间, 可能会有一段比较显著的时间间隔。

这不就是我们的特性吗,从刚刚的我们搜索大key的图中可以看到,我们有很多带超时的key并且size都很大,很有可能虽然已经超时了(即TTL变为0)但该数据并没有访问,并且由于R2M渐进式删除,某一个Key可能会在超时后很久才会被真正的物理删除

至此,直接原因的根本原因已经找到了。

2.1.2 解决

那么如何解决呢?根据一个Key过期时被物理删除的两种策略:

注意:

Redis 使用以下两种方式删除过期的键

  • 当一个键被访问时,程序会对这个键进行检查,如果键已经过期,那么该键将被删除。

  • 底层系统会在后台渐进地查找并删除那些过期的键,从而处理那些已经过期、但是不会被访问到的键。

首先通过访问的形式去删除数据肯定是愚蠢且没必要的(都能访问并且知道要过期了不如直接删除),那么可以选择提高渐进的查找速率。从而将那些超时的数据物理删除

于是我们联系了R2M对应运维:

image.png

根据上述聊天记录可知,确实有参数可以调整渐进式物理删除的频率,而我们的缓存集群则之前因为不知名原因(项目团队做过更换)被调整为了10,大约降低了六倍,此结果也符合我们的预期,从侧面印证了我们的猜想是正确的。

当时处于618前夕,我们没有并没有修改该参数,在618之后,我们随即提了工单修改该参数,将该参数从10提高到80:

image-20230713183643785

审批通过之后,我们观察r2m的下降速率:

image-20230713183917668

可以看到,在6.20号我们调整了参数后,在没有大批量数据添加后,r2m使用率的下降速率明显变快

至此,缓存使用率告警的直接原因已经解决完毕,真正的原因就是有大量的key过期后并没有被删除,观察后续缓存使用率都没有太高。此外,即时有大量的跑批任务,如果不是在同一天内直接添加,一般不会造成使用率过高的问题。

2.2 根本原因

上文在调整参数后,基本可以满足用户的日常业务需求,但是如果用户确实有一天之内有大量跑批任务的需求,那么此方案仍不能解决根本问题,还会造成使用率过高有可能影响线上业务的风险。

那么要从根本上解决此问题,就需要对跑批流程进行优化,按照1.2中流程示意以及原因分析:

  1. 样本就已经完全没有必要存储在缓存中,所以在代码中直接采用参数传递的方式传入给下一步流程。

  2. 结果分片肯定是有意义的,原因上文中也提到了,但是redis缓存的空间(即内存)是比较宝贵的,而oss的空间成本(硬盘)则是比较廉价的,并且考虑本身业务就是离线业务,时效性以及查询速率并不是最关键的因素,因此综合考虑将跑批的结果分片数据存储至oss

  3. 在跑批流程结束后,主动删除oss中的结果分片数据,避免数据无用后仍占用存储空间。此外在oss端设置7天自动删除,防止系统原因异常导致数据未删除而永久存在

综上,结合以上的优化思想,重新设计的流程图如下:

伏羲运营后台插入数据优化-第 4 页.drawio

至此,即时后续用户数据量再大,也无论是分一天创建还是多天创建,都不会导致缓存使用率告警而有可能带来的线上业务问题。

2.3 优化率

上线完成后的缓存使用情况:

image-20230911155108232

可以看到几乎是断崖式下降。

缓存优化率:

改造前

image-20230911155042608

改造后

image-20230911155540703

(8.35-0.17)/8.35≈97.96%

三、总结

本文主要通过一封告警邮件,由浅入深的将系统中存在的缓存问题与流程优化。在解决完实际问题后,我们应该都会有一些心得与总结,从而下次自己在开发过程中避免再犯这样的问题,也能够自己对自己再做一次总结与归档。要做到能够知其然更要知其所以然。以下总结是自己的由浅入深的一点点心得。

3.1 不同中间件应该负责不同的事

“韩信点兵,多多益善”,一名好的将军就是能将不同的士兵分配不同的职责,从而让士兵能够在自己擅长的领域内各尽其职。对我们研发来说,选择不同的中间件完成不同的功能则是能够反应我们研发的技术水平。

像本文来说,可供存储中间数据的有好多中间件,除了Redis、Oss,还有Mysql、Hive、ES、CK等,我们需要根据不同的业务需求选择不同的中间件完成对应的功能。本案例中很明显数据的特性为大量的、不要求速度的,而Redis的存储特性为少量的、快速的,很明显这两个是背道而驰的需求与业务,因此我们在选用时应该选择正确的中间件。

3.2 学习技术细节有没有用

其实之前也有学了很多的技术、框架的实现细节,但是绝大多数都是学完就学完了,并没有太多实践的环节。而这次案例分析正好处于之前刚刚学完Redis的相关细节,没隔多久就能够应用到本次的实践环节,算是理论与实践结合。此外这次案例也能够很大程度上提升自己的学习兴趣。

作者:京东科技 韩国凯

来源:京东云开发者社区 转载请注明来源

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

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

相关文章

如何看待Java上层技术与JVM

如何看待Java上层技术与JVM 你是否也遇到过这些问题 运行着的线上系统突然卡死,系统无法访问,甚至直接OOM!想解决线上JVM GC问题,但却无从下手。新项目上线,对各种JVM参数设置一脸茫然,直接默认吧&#x…

景联文数据标注:ChatGPT成功的秘密——人类反馈强化学习(RLHF)

ChatGPT的成功很大程度上归功于其采用的新的训练范式——人类反馈强化学习(RLHF)。RLHF是一种强化学习方法,它将强化学习与人类反馈相结合,通过利用人类提供的反馈来指导智能系统的行为,使其能够更加高效、快速地学习任…

分布式锁工具Redisson(Lua脚本)

如何实现分布式锁? Redis 可以通过 setnx(set if not exists)命令实现分布式锁 通过执行结果是否为 1 可以判断是否成功获取到锁 setnx mylock true 加锁del mylock 释放锁 分布式锁存在的问题: 死锁问题,未设置过…

运行在浏览器中的Domino Designer开发客户机

大家好,才是真的好。 首先讨论一个非常有意思的事情,就是有人问,如果我用很老的Lotus软件,它是免费的吗? 这估计代表了很多盆友的心声。但不太友好的是,即使你用很老的Lotus软件(例如Notes R4…

【2023集创赛】芯原杯一等奖作品:基于芯原DSP核的智能语音SoC设计

本文为2023年第七届全国大学生集成电路创新创业大赛(“集创赛”)芯原杯一等奖作品分享,参加极术社区的【有奖征集】分享你的2023集创赛作品,秀出作品风采,分享2023集创赛作品扩大影响力,更有丰富电子礼品等…

软件测试面试经验分享,真实面试题

前言 本人普通本科计算机专业,做测试也有3年的时间了,讲下我的经历,我刚毕业就进了一个小自研薪资还不错,有10.5k(个人觉得我很优秀),在里面呆了两年,积累了一些的经验和技能&#…

红米手机 导出 通讯录 到电脑保存

不要搞什么 云服务 不要安装什么 手机助手 不要安装 什么app 用 usb 线 连接 手机 和 电脑 手机上会跳出 提示 选择 仅传输文件 会出现下面的 一个 盘 进入 MIUI目录 然后进入 此电脑\Redmi Note 5\内部存储设备\MIUI\backup\AllBackup\20230927_043337 如何没有上面的文件&a…

Linux查找运行的Python脚本路径

目录 查看Python脚本进程id 根据进程ID找脚本路径 查看Python脚本进程id ps -ef|grep python 该命令会输出在运行中的Python脚本,找到你需要的Python脚本进程ID即可,进程ID如图: 根据进程ID找脚本路径 # 将PID替换为上一步中你拷贝的i…

项目03-基于Docker_Nginx+LVS+Flask+MySQL的高可用Web集群

文章目录 一.项目介绍1.拓扑图2.详细介绍 二.前期准备1.项目环境2.IP划分 三. 项目步骤1.ansible部署软件环境1.1 安装ansible环境1.2 建立免密通道1.3 ansible批量部署软件 2.部署nginx和lvs主从服务器2.1 docker配置nginx静态双web服务器从nfs主服务器上那页面数据2.2 使用ke…

DiskGenius -/ 20 年老牌匠心国产数据恢复、分区管理、备份还原软件!

数据恢复 / 分区管理 / 备份还原 20 年匠心开发,多功能磁盘工具软件! 数据恢复 DiskGenius 是一款专业级的 数据恢复软件 ,算法精湛、功能强大,用户群体广泛;支持各种情况下的文件恢复、分区恢复,恢复效果…

JavaSE16——抽象类(Abstract Class)

抽象类(Abstract Class) 1 抽象类概述 抽象类是面向对象编程中的一个重要概念,它是一种特殊的类。抽象类不能被实例化,只能用作其他类的基类(父类),通过继承抽象类来实现其子类的定义。 在继…

某瑞集团安全技术研发岗位面试

本文由掌控安全学院 - sbhglqy 投稿 一、自我介绍 阿吧阿吧,不多说 二、就ctf比赛经历方面提些问题 面试官:ctf打了多久了 我:两三年了。 面试官:得过什么奖项没有 我:本科的时候得过一个校一等奖。 面试官&#x…

跳槽去搞国产大模型,收入能涨多少?

原创:谭婧 夏尽秋来,2023年国产大模型看似喧闹已止,进入稳定竞争期。 作为一种新的IT解决方案,国产大模型一出生便伴随着激烈竞争。 外有GPT4,内有多家公司角逐“中国版ChatGPT”。 据我所知,就国内某家头部…

Mysql 子查询,最值查询

1.leetcode-184:查找部门内最高的薪水 首先是一个子查询,找出一个部门里最高的那个工资 随后查找最终需要的值,并且部门编号以及薪水应该包含在这个子查询中 最终答案: # Write your MySQL query statement below SELECT Depar…

全渠道客服体验:Rocket.Chat 的无缝互动 | 开源日报 No.41

RocketChat/Rocket.Chat Stars: 36.9k License: NOASSERTION Rocket.Chat 是一个完全可定制的开源通信平台,适用于具有高标准数据保护要求的组织。我们是团队沟通场景下的最终免费开源解决方案,可以实现同事之间、公司之间或客户之间的实时对话。提高生…

LiveGBS流媒体平台GB/T28181功能-海康大华摄像头接入无法语音对讲通道为0无法播放时候如何抓包分析windows抓包和Linux抓包

LiveGBS通道数为0无法播放的时候如何抓包分析windows抓包和Linux抓包 1、第一步:抓包工具准备1.1、Linux1.2、windows 2、第二步:找到设备出口ip3、第三步:执行命令抓设备出口ip3.1 Linux3.2 Windwos 4、第四步:触发相关页面操作4…

操作系统备考学习 day6(2.3.2 - 2.3.4)

操作系统备考学习 day6 第二章 进程与线程2.3 同步与互斥2.3.2 实现临界区互斥的基本方法单标记法双标志先检查法双标志后检查法Peterson算法 进程互斥的硬件实现方法中断屏蔽方法TestAndSet指令Swap指令 2.3.3 互斥锁2.3.4 信号量整型信号量记录型信号量 第二章 进程与线程 2…

安利上榜福布斯中国客户服务企业

9月25日至27日,福布斯中国、中国电子商会、保定市人民政府联合主办的“数智化服务产业发展论坛暨2022福布斯中国客户服务企业Top 100评选”在保定举办。活动通过剖析企业经营能力、企业服务能力、客服运营能力、企业发展潜力等多方面数据和信息,对数智化…

CH34X-MPHSI高速Master扩展应用—I2C设备调试

一、前言 本文介绍,基于USB2.0高速USB转接芯片CH347,配合厂商提供的USB转MPHSI(Multi Protocol High-Speed Serial Interface)Master总线驱动(CH34X-MPHSI-Master)为系统扩展I2C总线的用法,除…

python字符串前加r、f、u、l 的区别

嗨喽,大家好呀~这里是爱看美女的茜茜呐 👇 👇 👇 更多精彩机密、教程,尽在下方,赶紧点击了解吧~ python源码、视频教程、插件安装教程、资料我都准备好了,直接在文末名片自取就可 f-strings 是…