Redis集群慢查询问题排查经验分享,帮你快速定位隐患避免性能瓶颈
- 问答
- 2025-12-26 03:08:26
- 1
前段时间,我们线上一个核心业务的Redis集群时不时会冒出一些慢查询的告警,虽然还没到引发严重故障的地步,但就像鞋子里有颗小石子,不解决掉总让人不放心,我花了一些时间把这个问题彻底梳理了一遍,形成了一些比较实用的排查经验,在这里分享给你,整个过程,说白了就是顺着“谁、在什么时候、做了什么慢操作”这条线往下挖。
第一步:确认慢查询的存在和范围
你得知道Redis自己是怎么定义“慢”的,这个标准是可以调的,通过配置文件里的 slowlog-log-slower-than 参数,单位是微秒,比如设置成10000,就代表执行时间超过10毫秒的命令会被记录下来,我们当时设置的是5毫秒,第一件事就是连接上出问题的Redis节点,用 SLOWLOG GET [数量] 命令把最近的慢查询日志拉出来看看,这个命令返回的结果很直观,会告诉你每条慢查询的ID、发生的时间戳、耗时、具体命令以及客户端信息,这里要注意,Redis的慢日志是存在内存里的,有长度限制(用 slowlog-max-len 配置),太旧的会被挤掉,所以发现问题要尽快查。
第二步:分析慢查询命令本身
拿到慢日志列表后,重点看那个“具体命令”字段,大部分慢查询的根源都出在命令的使用方式上,根据我们的经验(来源:Redis官方文档以及一些技术社区像Stack Overflow的案例),常见的有这么几类:

- “大Key”操作: 这是最典型的凶手,比如对一个存储了几万条数据的Hash键执行
HGETALL,或者对一个超长的List键执行LRANGE 0 -1,这种操作会一次性拉取大量数据,不仅耗时长,还会严重占用网络带宽和CPU,你需要检查慢查询里的Key,看看是不是有这种“庞然大物”。 - 复杂度高的命令: 有些命令天生就比较“慢”,尤其是在数据量大的时候。
KEYS命令(用来模糊匹配所有键),它的时间复杂度是O(N),N是数据库里的键总数,在生产环境执行这个命令简直就是灾难,还有SORT、ZUNIONSTORE等命令,如果处理的数据集很大,也会很慢。 - 不当的批量操作: 比如在循环里频繁执行
GET、SET,而不是使用MGET、MSET这样的批量命令,网络来回的开销累积起来非常可观。
第三步:结合业务上下文,寻找根源
光看命令本身有时候还不够,你得知道这个命令为什么会被这样调用,这时候就需要结合日志里的时间戳和客户端信息了。
- 时间点关联: 查看慢查询发生的时间点,是不是和业务上的某个定时任务、促销活动开始、或者数据批量导入的时间点重合?我们当时就发现,慢查询的高峰期正好对应着一个每天凌晨运行的报表生成任务,这个任务会大量读取一些复杂的聚合数据。
- 客户端信息: 慢日志里会记录客户端的IP和端口,你可以根据这个信息去对应的应用服务器上,查找同一时间段的业务日志,看看当时应用在执行什么逻辑,为什么会发出这样一个慢查询,是不是代码里有bug,导致了循环调用?或者是新上线的功能没有经过充分的性能测试?
第四步:不是所有“慢”都是Redis的锅

命令在Redis服务器端执行得很快,但客户端感觉还是很“慢”,这时候就要怀疑网络问题了,可能是客户端和Redis集群之间的网络延迟过高,或者出现了丢包,你可以用 ping 命令简单测试一下网络延迟,或者使用更专业的网络诊断工具,如果Redis服务器的CPU、内存或网络带宽资源用尽了,也会导致所有命令的处理变慢,这时候需要监控系统来帮忙定位资源瓶颈。
第五步:解决与优化
找到原因后,解决办法就相对明确了:
- 对于“大Key”:进行拆分,比如一个大Hash可以按某个维度拆成多个小Hash;或者把全量查询改成增量查询,用
HSCAN代替HGETALL。 - 对于复杂命令:用替代方案,比如用
SCAN命令渐进式地替代KEYS;对需要排序查询的数据,考虑是否能在写入时就处理好,而不是每次都现场计算。 - 对于批量操作:优化代码,尽量使用管道(pipeline)或者批量命令,减少网络往返次数。
- 对于资源瓶颈:可能是时候考虑给Redis集群扩容了,或者优化一下数据结构,减少内存占用。
建议把慢查询监控常态化,可以定期采集慢日志,做个简单的统计分析,看看有没有新的慢查询模式出现,这样才能在问题扩大之前就把它解决掉,这次排查给我们的启示是,Redis的性能问题大多源于使用姿势不对,养成良好的使用习惯,时刻对“大Key”和“慢命令”保持警惕,是避免性能瓶颈的关键。
本文由称怜于2025-12-26发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/68542.html
