slowlog get 返回空不代表无慢查询,而是因默认阈值10ms过高导致2–5ms毛刺未被捕获,或slowlog-max-len过小致日志被覆盖;应调低阈值至1ms并增大日志长度。

为什么 SLOWLOG GET 返回空,但业务明显卡顿
不是没慢查询,而是阈值设太高或日志被覆盖了。slowlog-log-slower-than 默认是 10000(10ms),很多毛刺在 2–5ms 区间,根本进不了日志。线上排查建议先调低:
-
CONFIG SET slowlog-log-slower-than 1000(1ms,适合高敏场景) -
CONFIG SET slowlog-max-len 1000(避免关键记录被挤掉) - 改完立刻
SLOWLOG GET 5看是否出数据,别等“自然积累”
SLOWLOG GET 不清空日志,但某些旧版客户端或脚本封装可能误加 RESET,导致刚查完就没了——查之前先 SLOWLOG LEN 确认有存量。
从 SLOWLOG 输出里快速识别真瓶颈
看三列:时间戳、耗时(第三字段)、命令数组(第四字段)。重点不是命令名,而是耗时数值和参数特征:
- 耗时集中在
5000–50000(5–50ms):大概率是大 key 的LRANGE、HGETALL或KEYS,不是网络或排队问题 - 耗时稳定在
100–500(微秒级)但频次极高:可能是客户端高频轮询小 key,压垮了单线程吞吐,得看INFO COMMANDSTATS验证 - 命令参数里带
"*"或长数字范围(如"0","-1"):基本锁定是全量拉取,该换SCAN或分页了 - 出现大量
EVAL且耗时不一:Lua 脚本内部逻辑有问题,SLOWLOG只记起点,得去脚本里加redis.log()打点
集群环境下怎么知道慢的是哪个节点、哪个 key
SLOWLOG 是实例级的,不跨节点,也不暴露 slot 信息。必须手动关联:
- 从
SLOWLOG GET 1提取第一个参数(比如"GET"后面那个"user:1001") - 连到同一节点执行:
CLUSTER KEYSLOT user:1001得到 slot 编号 - 再执行:
CLUSTER GETKEYSINSLOT {slot} 1,确认这个 key 确实在当前节点;如果返回空,说明实际路由到了别的节点(常见于没加哈希标签{}或用了MGET跨 slot) - 配合
CLIENT LIST看对应客户端 IP 和端口,反向查服务日志,确认是不是它在密集重试
SET lock:xxx 就是锁问题”——Redis 的 NX 操作本身几乎不耗时,卡住的是客户端 sleep 重试逻辑。
哪些情况 SLOWLOG 根本帮不上忙
它只记录 Redis server 线程内执行阶段的耗时,以下完全看不到:
- 客户端发完命令后干等响应(TCP 延迟、丢包、客户端阻塞)
-
pipeline中单条命令的排队时间——SLOWLOG记的是整批执行总耗时 -
BLPOP在无数据时挂起的时间(只有真正 pop 到数据那一下才计时) - 模块(Module)里写的 C 函数,若没显式调用
slowlogPushEntryIfNeeded() - AOF rewrite 或 RDB save 过程中临时跳过的日志采集
LATENCY DOCTOR 或链路追踪(如 SkyWalking)看端到端耗时分布,否则容易在错误方向上浪费半天。
真正难的不是查出哪条命令慢,而是判断这个“慢”是 Redis 内部真实压力,还是上游重试/跨服务锁等待制造的假象——SLOWLOG 只能帮你划清这条线,跨过去的事,得换工具。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。










