Redis key为何神秘消失,真相究竟何在?
摘要:本文从一次生产环境业务服务报错,逐步对问题进行定位,深入分析之后发现导致问题的原因,给出相应的优化方法,提升业务可用性。
作者: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请求也少量增长。
