3、慢查询日志查看:SLOWLOG GET、SLOWLOG LEN、SLOWLOG RESET 与日志格式解析

慢查询日志是 Redis 性能诊断的第一手现场证据。当某个命令的执行耗时超过 slowlog-log-slower-than 阈值(默认 10 毫秒),Redis 会将该命令的上下文记录到内存中的慢查询队列。本章将系统讲解如何通过 SLOWLOG 系列命令查看、统计与重置日志,并逐字段解析日志格式,帮助你快速定位慢命令的根因。

3.1 核心命令速查

命令 功能 常用示例
SLOWLOG GET [n] 返回最近 n 条慢查询日志(默认 10 条) SLOWLOG GET 100
SLOWLOG LEN 返回当前慢查询队列中的日志总数 SLOWLOG LEN
SLOWLOG RESET 清空所有慢查询日志 SLOWLOG RESET
提示: SLOWLOG GET 返回的日志条数受 slowlog-max-len 限制(默认 128 条)。超出上限后,最旧的日志会被自动丢弃,因此建议定期归档或调大该参数。

3.2 SLOWLOG GET 命令详解

SLOWLOG GET 是最常用的诊断命令,返回结果是一个数组,每个元素代表一条慢查询日志。不传参数时默认返回最近 10 条;传入数字 n 则返回最近 n 条。

# 查看最近 5 条慢查询日志
127.0.0.1:6379> SLOWLOG GET 5
1) 1) (integer) 14
   2) (integer) 1712345678
   3) (integer) 12034
   4) 1) "KEYS"
      2) "user:*"
   5) "127.0.0.1:54321"
   6) ""
2) 1) (integer) 13
   2) (integer) 1712345670
   3) (integer) 15002
   4) 1) "SORT"
      2) "cache:list"
      3) "BY"
      4) "weight_*"
   5) "127.0.0.1:54320"
   6) ""
生产建议: 线上排查时优先使用 SLOWLOG GET 100 获取足够样本,结合 CLIENT LIST 和 MONITOR 交叉验证客户端来源与命令模式。

3.3 SLOWLOG LEN 与 SLOWLOG RESET

  • SLOWLOG LEN:返回当前队列中的日志总数,用于判断慢查询是否频繁。如果 LEN 持续接近 slowlog-max-len,说明系统存在持续性的慢操作。
  • SLOWLOG RESET:清空所有日志。通常在以下场景使用:
    • 调整 slowlog-log-slower-than 阈值后,清除旧日志以便观察新阈值下的记录。
    • 定位问题前清空队列,确保后续只捕获到目标时间窗口内的慢查询。
# 查看当前队列长度
127.0.0.1:6379> SLOWLOG LEN
(integer) 42

# 清空所有慢查询日志
127.0.0.1:6379> SLOWLOG RESET
OK

# 确认已清空
127.0.0.1:6379> SLOWLOG LEN
(integer) 0
注意: SLOWLOG RESET 不可逆,执行后所有历史日志将永久丢失。建议在重置前先通过 SLOWLOG GET 导出并归档关键日志。

3.4 日志格式逐字段解析

每条慢查询日志是一个包含 6 个字段的数组,字段顺序固定。下面以一条真实日志为例进行拆解:

1) (integer) 14          # 字段1:日志唯一ID(自增)
2) (integer) 1712345678  # 字段2:命令执行时的Unix时间戳(秒)
3) (integer) 12034       # 字段3:命令执行耗时(微秒)
4) 1) "KEYS"             # 字段4:命令及参数(数组形式)
   2) "user:*"
5) "127.0.0.1:54321"     # 字段5:客户端IP和端口
6) ""                     # 字段6:客户端名称(默认空)
字段索引 含义 数据类型 典型值示例
1 日志唯一 ID(自增整数) integer 14
2 命令执行的 Unix 时间戳(秒) integer 1712345678
3 命令执行耗时(微秒) integer 12034
4 命令及其参数(数组) array ["KEYS", "user:*"]
5 客户端 IP 和端口 string "127.0.0.1:54321"
6 客户端名称(通过 CLIENT SETNAME 设置) string "my-app" 或 ""
关键解读: 字段 3 的单位是微秒(1 秒 = 1,000,000 微秒)。如果该值超过 10,000(即 10 毫秒),说明该命令已触发默认慢查询阈值。字段 4 中的命令参数可能包含敏感数据(如密码),生产环境归档时建议脱敏。

3.5 慢查询日志生命周期与队列结构

下图展示了慢查询日志从触发到被查看、淘汰的完整生命周期,以及 SLOWLOG GET、SLOWLOG LEN、SLOWLOG RESET 三个命令在其中的作用位置。

慢查询日志生命周期与查看命令 命令执行 耗时 > 阈值? 写入慢查询队列 队列满 → 淘汰最旧 SLOWLOG GET SLOWLOG LEN SLOWLOG RESET 否(不记录) 自动触发 说明: SLOWLOG GET 读取队列;SLOWLOG LEN 统计队列长度;SLOWLOG RESET 清空整个队列。 队列满时自动淘汰最旧日志,不影响新日志写入。

3.6 实战:一次完整的慢查询排查流程

  1. 查看队列长度:执行 SLOWLOG LEN,判断慢查询是否频繁。如果长度接近 slowlog-max-len,说明系统存在持续慢操作。
  2. 获取日志样本:执行 SLOWLOG GET 20,提取最近 20 条日志。
  3. 解析耗时字段:关注字段 3(微秒),将值除以 1000 转换为毫秒,筛选出耗时最高的命令。
  4. 定位危险命令:字段 4 中的命令类型是关键。常见慢命令包括 KEYS、SORT、LREM、ZRANGE(大数据集)、MGET(大键值)、DEL(大集合)。
  5. 溯源客户端:字段 5 的 IP:端口 和字段 6 的客户端名称帮助定位是哪个应用或实例发出的慢命令。
  6. 重置并监控:执行 SLOWLOG RESET 清空旧日志,持续观察新产生的慢查询是否减少。
案例: 某业务 Redis 实例 CPU 持续 80%+,执行 SLOWLOG GET 10 发现 8 条都是 KEYS user:*,耗时 30~50 毫秒。改用 SCAN 命令后,CPU 降至 30%,慢查询日志清零。

3.7 日志字段与排查要点对照

字段 排查要点 常见问题
ID 观察 ID 是否连续,判断是否有日志被淘汰 ID 跳跃过大 → 队列满导致日志丢失
时间戳 转换为可读时间,确认慢查询是否集中在业务高峰期 集中在整点 → 定时任务或缓存预热
耗时(微秒) 除以 1000 得毫秒,与业务容忍度对比 > 100,000 微秒(100ms)→ 严重慢查询
命令及参数 识别命令类型和 key 模式 KEYS、FLUSHALL、SORT、大 key 操作
客户端地址 关联应用实例 IP,确认是否来自预期来源 异常 IP → 可能存在未授权的访问
客户端名称 通过 CLIENT SETNAME 区分不同业务模块 名称为空 → 建议统一设置便于溯源
注意: 慢查询日志只记录命令在 Redis 服务端的执行耗时,不包含网络传输时间和客户端排队时间。如果客户端感知到延迟但慢查询日志为空,应排查网络带宽、连接池配置或客户端阻塞。