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 字段关系与执行流程
下图展示了慢查询日志各字段在命令执行生命周期中的采集位置:
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 字段与慢查询日志的生命周期
下图展示了慢查询日志从产生到淘汰的完整生命周期:
4.7 小结
- id:唯一标识,单调递增,重启重置。
- timestamp:秒级 UTC 时间,记录命令开始时刻。
- duration:微秒级耗时,不包含网络延迟。
- command与argv:命令快照,注意截断和敏感信息。
- 理解这四个字段的精确含义,是正确解读慢查询日志、定位性能瓶颈的第一步。