4. 慢查询日志的四大字段:id、timestamp、duration、command与argv的深度解读

Redis 慢查询日志(Slow Log)是定位延迟问题的第一道防线。每条慢查询记录由四个核心字段构成:id、timestamp、duration、command与argv。理解这些字段的精确含义、取值边界和潜在陷阱,是高效使用慢查询日志的前提。

4.1 四大字段概览

字段 类型 说明 典型值示例
id uint64 慢查询日志的唯一递增序号,从 0 开始,每新增一条 +1 0, 1, 2, …
timestamp unix 时间戳(秒) 命令开始执行时的系统时间,单位秒 1712345678
duration 微秒(μs) 命令从入队到执行完毕的总耗时,单位微秒 12045
command与argv 数组 命令名称及参数列表,按空格分隔 ["KEYS", "user:*"]
关键认知:duration 的单位是微秒,而非毫秒。很多开发者误以为单位是毫秒,导致对慢查询的严重程度判断失误。一条耗时 10000 μs 的命令,实际耗时 10 ms,在毫秒级视角下可能被忽略。

4.2 字段深度解读

4.2.1 id:单调递增的日志序号

  • 递增规则:id 从 0 开始,每记录一条慢查询就 +1,重启 Redis 后重置为 0。
  • 回绕行为:当日志数量达到 slowlog-max-len 上限时,最旧的记录被淘汰,id 继续递增,不会复用已淘汰的 id。
  • 用途:用于精确追踪某条慢查询记录,尤其在批量导出或对比分析时,id 是唯一标识。

4.2.2 timestamp:命令开始时间

  • 精度:秒级,不包含毫秒或微秒部分。
  • 时间点:记录的是命令开始执行的时间,而非结束时间。如果命令耗时很长,结束时间 = timestamp + duration(需单位换算)。
  • 时区:始终为 UTC 时间,不随 Redis 配置或系统时区变化。查看日志时需手动转换为本地时间。

4.2.3 duration:真正的耗时指标

  • 测量范围:从命令进入 Redis 的事件循环(before sleep)开始,到命令执行完毕、准备返回结果为止。包括:命令解析、执行、数据操作、网络发送前的序列化等。
  • 不包含:客户端与服务器之间的网络传输时间、命令在输入缓冲区排队等待的时间。
  • 阈值判断:只有 duration 超过 slowlog-log-slower-than 设置的值(单位微秒)时,才会被记录。
常见误区:duration 不包含网络往返时间(RTT)。如果客户端观察到命令总耗时 50 ms,而慢查询日志显示 duration 只有 5 ms,说明瓶颈在网络或客户端,而非 Redis 服务端。

4.2.4 command与argv:命令的完整快照

  • 结构:数组形式,第一个元素是命令名称(大写),后续元素是参数。
  • 长度限制:Redis 默认只记录命令的前 128 个字符(可通过 slowlog-log-args-len 配置调整)。超长参数会被截断,末尾追加 ...。
  • 敏感信息:如果命令包含密码、令牌等敏感数据,慢查询日志会明文记录,存在安全风险。

4.3 字段关系与执行流程

下图展示了慢查询日志各字段在命令执行生命周期中的采集位置:

慢查询日志字段采集流程 客户端 输入缓冲区 命令执行器 数据操作 timestamp 采集点 duration 测量区间(命令入队 → 执行完毕) command与argv 采集点 id 生成点(写入日志时)

4.4 字段使用实战

4.4.1 查看慢查询日志

# 获取最近 10 条慢查询记录
SLOWLOG GET 10

# 输出示例(每条记录为一个数组)
1) 1) (integer) 0           # id
   2) (integer) 1712345678  # timestamp
   3) (integer) 12045       # duration (微秒)
   4) 1) "KEYS"             # command
      2) "user:*"           # argv
   5) "127.0.0.1:6379"      # 客户端地址(Redis 6.0+ 新增)
   6) "conn-12345"          # 连接名称(可选)

4.4.2 计算实际执行时间

# 将 duration 从微秒转换为毫秒
# 假设 duration = 12045 μs
实际耗时(ms) = 12045 / 1000 = 12.045 ms

# 计算命令结束时间(UTC)
结束时间 = timestamp + (duration / 1000000)
         = 1712345678 + 0.012045
         = 1712345678.012045

4.4.3 配置慢查询阈值与日志长度

# 设置慢查询阈值为 10 毫秒(10000 微秒)
CONFIG SET slowlog-log-slower-than 10000

# 设置最多保留 128 条慢查询记录
CONFIG SET slowlog-max-len 128

# 设置命令参数最大记录长度(默认 128 字符)
CONFIG SET slowlog-log-args-len 256

4.5 字段常见陷阱与避坑指南

陷阱 表现 正确理解
duration 单位误判 认为 12045 是 12 秒 实际是 12 毫秒,单位是微秒
timestamp 精度不足 多条日志 timestamp 相同 秒级精度,同一秒内的多条日志无法区分先后
命令参数被截断 看到 "SET key value..." 但看不到完整 value 检查 slowlog-log-args-len 配置,或增大该值
id 回绕误解 认为 id 从 0 开始是日志被清空 可能是 Redis 重启导致 id 重置
忽略客户端地址 只关注命令本身,无法定位来源 Redis 6.0+ 的慢查询日志包含客户端 IP 和端口
最佳实践:在分析慢查询日志时,始终将 duration 除以 1000 转换为毫秒后再评估。同时,结合 timestamp 和客户端地址,可以快速定位是哪个应用、哪个时间段的哪些命令导致了延迟。

4.6 字段与慢查询日志的生命周期

下图展示了慢查询日志从产生到淘汰的完整生命周期:

慢查询日志生命周期 命令执行 duration 超过阈值 日志生成 分配 id,记录字段 日志存储 追加到链表尾部 日志淘汰 超出 max-len 时移除 关键说明 • id 在日志生成阶段分配,单调递增,重启后重置 • timestamp 在命令开始执行时采集,秒级精度 • duration 在命令执行完毕后计算,单位微秒

4.7 小结

  • id:唯一标识,单调递增,重启重置。
  • timestamp:秒级 UTC 时间,记录命令开始时刻。
  • duration:微秒级耗时,不包含网络延迟。
  • command与argv:命令快照,注意截断和敏感信息。
  • 理解这四个字段的精确含义,是正确解读慢查询日志、定位性能瓶颈的第一步。