slowlog不是查死锁的工具,而是排除“真慢”和定位“假慢”的分水岭;它只记录命令总耗时,不区分CPU、网络或锁等待,无法反映业务层多资源联锁导致的死锁。

slowlog 本身不记录死锁,它只记录单条命令的执行耗时。所谓“复杂业务的性能死锁”,比如多资源联锁顺序不一致导致的线程卡住,slowlog 是看不到的——它只会显示某次 GET 或 SET 耗了 8ms,但不会告诉你这个 key 正被另一个服务死死 hold 着、而对方又在等你释放另一个 key。
所以第一步得明确:**慢日志不是查死锁的工具,而是排除“真慢”和定位“假慢”的分水岭**。
为什么 slowlog 里找不到死锁线索?
slowlog 只捕获命令从进入队列到返回结果的总耗时,不区分是 CPU 计算慢、网络延迟慢、还是等待锁慢。Redis 单线程模型下,加锁(如 SET key val NX EX 10)本身是原子操作、几乎不耗时;真正卡住的是客户端层面的重试逻辑或业务层的串行等待。比如:
- 订单服务调用
redis.set("stock:1001", "locked", nx=True, ex=10)成功,接着去请求优惠券服务 - 优惠券服务也尝试
redis.set("coupon:2002", ...),但发现已被占用,于是 sleep(100ms) 后重试 - 此时 Redis 的
slowlog里只有两条毫秒级SET记录,完全看不出“等锁”行为
换句话说,死锁发生在业务代码和跨服务协调层,不在 Redis 命令执行路径里。
如何用 slowlog 辅助判断是否为“伪死锁”?
当接口响应变长、疑似死锁时,先看 slowlog 是否有异常峰值:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 如果
slowlog get 10返回大量LRANGE、HGETALL、SUNION等 O(N) 命令,且耗时集中在 5–50ms 区间 → 很可能是大 key 或高频全量拉取压垮了主线程,不是死锁,是真慢 - 如果
slowlog干净,但监控显示连接数暴涨、客户端超时激增 → 更倾向是客户端重试风暴或服务间锁等待,需转向链路追踪(如 SkyWalking 中看 RPC 耗时分布)和 Redisson 的lockWatchdogTimeout日志 - 若某段时间内
slowlog出现密集的EVAL(尤其含while true do或长循环 Lua),说明可能有人用 Lua 实现了自旋锁,这会直接阻塞 Redis 线程 → 这是危险的“伪死锁”,必须禁用
排查联锁死锁时,slowlog 配合什么才有效?
单独看 slowlog 没用,但它可以帮你快速过滤掉干扰项。真正要定位多资源死锁,得组合以下三件事:
- 开启
slowlog-log-slower-than到 1000(1ms),确认没有底层命令拖慢整体节奏;否则所有上层等待都只是表象 - 检查 Redisson 或 Lettuce 客户端日志,重点搜
tryLock失败后是否漏掉unlock,或forceUnlock调用失败残留锁 - 导出所有被锁 key 的 TTL 和 client list,运行
redis-cli --scan --pattern "lock:*" | xargs -I{} redis-cli ttl {},看是否存在长期未释放的锁(如 TTL 持续 >60s)
最常被忽略的一点:Redis 本身没死锁概念,但业务代码里对锁 key 的命名没做全局排序(比如库存用 lock:stock:1001,优惠券用 lock:coupon:2002),就等于把死锁风险甩给了运维——slowlog 永远抓不到这个 bug,只能靠代码规范和上线前的锁路径审计。


















