背景:
某证券公司APP业务,使用了腾讯云的云数据库redis(TencentDB for Redis)集群版本,2024.6.20运维童鞋反馈,近几周redis的内存量增长很快,日均增加2%,redis集群已经接近80%使用内存(图片待补充)
排查过程:
排查内存暴涨原因:
腾讯云提供的运维平台只能看出来某些bigkey,但咨询业务开发后发现该bigkey的数量可控,不会是引起内存暴涨的原因。
腾讯云运维平台,无法根据key前缀显示内存大小,此时无法定位到是哪些key引起的,问题卡在这里。
新的排查思路:
(1)根据运维反馈,是最近几周redis才开始出现内存暴涨问题,猜测可能原因是最近几周新上的某些业务写入了很多用户维度的key。
(2)如果我们能登录到某个redis存储节点上 ,用scan指令查看是否有大量相同前缀的key,或许就能够找到一些思路。
(3)顺着这个思路, 结合之前关于redis集群的相关知识储备,在集群模式下,redis客户端会拿到集群下所有的node节点,维护所有的分片node(16384槽位的一部分)的ip,然后针对该ip进行读写操作。 因为生产环境执行scan指令比较危险,所以打算复刻一份数据到测试环境进行检测
(4)运维 下载 生产的RDB文件, 整库备份到测试环境的redis中
(5)登录到redis的测试集群,执行scan指令,发现报错
(6)查找腾讯云官方文档,原来腾讯云提供的redis服务,对redis进行了一层proxy封装,和原生的redis集群模式有所区别
暴露给客户端的永远只有一个proxy ip,对于原生的redis集群 node,对租户是不可见的。。。
(7)作为一个公有云,肯定有提供别的操作方式才对,连到proxy节点上,执行
cluster nodes 指令,发现确实没有暴露出来后端node节点的ip,但是有nodeid:
再进一步查看腾讯云文档,发现有对应的scan指令说明:
(8)使用scan自定义指令:
scan 0 count 1000 64349c209c161a1219c48cbc18f915e791a513c3
scan 0 count 1000 a1b0a674801a7b084df5cf3cbe034d593c1c70b0
查看各nodeid对应的数据分布情况,发现的确有大量前缀为growthCenter的key,并且没有设置超时时间
(9)找到该key对应的业务方,咨询后发现,的确是近期新上线业务,是为了对领奖做幂等,根据custno+msgno做的幂等key,并且没有设置超时时间…
(10)找该业务开发出方案删除缓存key,问题解决!!!
反思:
(1)rediskey为什么不设置超时时间,CR代码重要性
(2)市面上有redis key分析工具,可根据redis key前缀分析内存占比,一键找出罪魁祸首key,如 RDR(Redis Data Reveal)工具
工具参考:https://cloud.tencent.com/developer/article/1433048
(3)对使用的中间件,需要有足够熟悉度,比如redis集群采用了前置proxy, 了解底层原理:
腾讯云redis文档:https://cloud.tencent.com/document/product/239