← 返回最佳实践列表

*Redis 慢查询日志分析:SLOWLOG 配置与延迟排查

Redis 慢查询日志用于记录服务器端执行时间超过阈值的命令,是定位大 Key、高复杂度命令和阻塞操作的重要工具。本文说明 SLOWLOG 的配置、字段含义和分析方法,并区分慢命令、网络等待、连接池排队与持久化造成的延迟。

*SLOWLOG 记录的是什么

slowlog-log-slower-than 的单位是微秒。命令执行时间超过该阈值时,Redis 将命令加入内存中的慢查询日志。它主要统计命令在服务器执行阶段的时间,不包括完整的网络往返、客户端连接池等待和客户端反序列化时间。

因此会出现两种看似矛盾的情况:

  • 客户端请求很慢,但 SLOWLOG 没有记录:瓶颈可能在网络、连接池、客户端 CPU、TLS 或服务器事件循环的其他阶段。
  • SLOWLOG 中存在慢命令,但平均响应仍正常:少量大对象操作可能只影响尾延迟,需要结合 P95、P99 和发生时间判断。

SLOWLOG 不是完整访问日志,也不能替代应用侧链路追踪。

*配置慢查询日志

以下示例将阈值设为 10 毫秒,最多保留 256 条记录:

slowlog-log-slower-than 10000
slowlog-max-len 256

运行中可临时调整:

redis-cli CONFIG SET slowlog-log-slower-than 10000
redis-cli CONFIG SET slowlog-max-len 256
redis-cli CONFIG GET slowlog-log-slower-than slowlog-max-len

CONFIG SET 不等于已经写入配置文件。需要重启后仍生效时,应通过配置管理更新 redis.conf 或执行受控的 CONFIG REWRITE,并确认部署系统不会覆盖该修改。

将阈值设为 0 会记录所有命令,可能增加内存和观测开销;设为负数则禁用慢查询日志。生产环境不要长期用全量记录代替抽样监控。日志长度应结合命令量和排查窗口设置,过短时旧记录会被快速覆盖。

*读懂 SLOWLOG GET

redis-cli SLOWLOG LEN
redis-cli SLOWLOG GET 10

一条典型记录包含:

1) (integer) 18
2) (integer) 1763000000
3) (integer) 15240
4) 1) "HGETALL"
   2) "user:1000"
5) "10.0.0.8:52344"
6) "app-worker"

各字段依次表示:

  1. 日志条目 ID,只在当前日志内容中用于识别条目。
  2. Unix 时间戳,用于和应用监控对齐。
  3. 执行耗时,单位为微秒;示例为 15.24 毫秒。
  4. 命令及参数,较长参数可能被截断。
  5. 客户端地址和端口,具体可用信息取决于版本与连接方式。
  6. 客户端名称,可通过 CLIENT SETNAME 设置,便于定位调用方。

日志可能包含业务键值、令牌或其他敏感参数。导出排障信息时应限制权限并脱敏,不要把完整输出直接贴到公共工单。

需要清理旧记录时可使用:

redis-cli SLOWLOG RESET

RESET 会删除当前实例的全部慢查询记录,执行前应先保存需要分析的内容。主节点和副本各自维护慢查询日志,检查多个节点时不要把单个节点的结果当作整个集群的结论。

*从慢命令定位根因

*检查命令复杂度和返回大小

以下命令在大数据量上容易产生高耗时或大响应:

操作 风险 常见改法
KEYS * 遍历整个键空间,阻塞其他命令 使用 SCAN 游标分批处理
HGETALL 大哈希 遍历并返回全部字段 用 HMGET 取所需字段,或用 HSCAN 分批
SMEMBERS 大集合 返回全部成员并占用网络带宽 用 SSCAN,或重新设计数据模型
LRANGE 0 -1 长列表 返回整个列表 按页读取,限制列表长度
大范围 ZRANGE 排序集合结果过大 限制范围,按需分页
大集合交并差 计算量随输入规模增长 缩小输入,离线计算或拆分任务
删除大对象 同步释放内存可能产生延迟 评估 UNLINK,并从根本上控制对象大小

SCAN 只是避免一次遍历整个键空间,不代表完整扫描没有成本。后台扫描仍应限速,并避免多个任务同时扫描同一实例。

*按命令汇总统计

redis-cli INFO commandstats

输出中的 calls 表示累计调用次数,usec 表示累计执行微秒数,usec_per_call 是累计平均值。平均值不能反映 P99,也无法单独说明某次故障;应在两个时间点之间计算增量,并与 QPS、慢查询和客户端指标对照。

INFO commandstats 的统计范围与实例生命周期和配置有关。使用 CONFIG RESETSTAT 会重置多项统计,不应只为临时观察而在生产中随意执行。

*检查大 Key 和热 Key

redis-cli --bigkeys
redis-cli MEMORY USAGE user:1000 SAMPLES 100

--bigkeys 适合发现线索,不等于完整内存审计。某个键耗时高也可能是访问频率过高,而不只是体积过大。具体治理见大 Key 与热 Key 排查。

*客户端慢但 SLOWLOG 为空时怎么查

现象 优先检查 建议证据
所有实例或接口同时变慢 网络、DNS、TLS、代理、宿主机 客户端分阶段耗时、网络重传、redis-cli --latency
只有部分应用实例变慢 客户端 CPU、GC、连接池、序列化 池等待时间、线程/协程指标、进程 CPU
高峰期排队,单命令很快 连接池过小或请求批量过大 获取连接耗时、池占用、Pipeline 批次大小
周期性延迟尖峰 RDB/AOF、fork、磁盘和定时任务 latest_fork_usec、持久化状态、磁盘延迟
单个集群分片变慢 热点槽、节点资源、网络 分片级 QPS、CPU、带宽和键分布
故障后请求大量超时 重试风暴和连接重建 重试次数、退避、连接数、 rejected connections

从客户端同网段测量 Redis 延迟:

redis-cli --latency -h 127.0.0.1 -p 6379
redis-cli --latency-history -h 127.0.0.1 -p 6379

本机测试和远程测试回答的问题不同。服务器本机延迟低而远程延迟高时,应继续检查网络路径、连接池和客户端,而不是直接调整 Redis 命令阈值。

*用延迟监控补充 SLOWLOG

Redis 延迟监控可记录执行过程中超过阈值的延迟事件。示例配置:

latency-monitor-threshold 100

该阈值单位是毫秒,设为 0 表示关闭。常用命令:

redis-cli LATENCY LATEST
redis-cli LATENCY HISTORY command
redis-cli LATENCY DOCTOR

LATENCY DOCTOR 提供诊断线索,但不会替代完整的指标和日志。可结合以下信息判断周期性尖峰:

redis-cli INFO persistence
redis-cli INFO memory
redis-cli INFO clients
redis-cli INFO stats

重点检查 latest_fork_usec、RDB/AOF 状态、内存压力、拒绝连接和客户端输出缓冲。不要只凭一项指标就修改内核参数或持久化策略。

*谨慎使用 MONITOR

redis-cli MONITOR

MONITOR 会持续输出服务器处理的命令,适合短时间、受控的调试。它可能明显增加服务器和网络开销,并暴露敏感参数。生产环境应优先使用 SLOWLOG、命令统计和客户端采样,避免长时间运行 MONITOR。

*建立可执行的排查流程

  1. 在客户端记录连接池等待、连接建立、命令发送、首字节响应和反序列化耗时。
  2. 按实例和命令统计 P50、P95、P99,而不是只看总体平均值。
  3. 保留慢查询日志,并将时间戳与应用错误、发布和定时任务对齐。
  4. 对慢命令检查复杂度、大 Key、返回值大小和访问频率。
  5. SLOWLOG 没有异常时,转向网络、连接池、持久化、操作系统和集群倾斜。
  6. 每次只调整一个变量,用相同数据和负载复测,确认优化没有牺牲数据安全。

*常见问题

*慢查询阈值设置为 10 毫秒是否通用

不是。阈值应根据业务延迟目标、命令基线和日志保留窗口确定。对低延迟在线服务,10 毫秒可能已经很高;对离线批处理,它可能产生过多记录。

*为什么 usec_per_call 很低,用户仍然超时

它主要是服务器端累计平均值,不包含所有客户端等待,也无法表达尾延迟。应检查分位延迟、连接池、网络和单次大结果处理。

*Pipeline 能消除慢查询吗

不能。Pipeline 主要减少网络往返,不会降低单条命令的算法复杂度。过大的 Pipeline 还可能占用输出缓冲并扩大单次等待,应控制批次规模。

相关阅读:Redis 性能优化指南、延迟问题排查、延迟监控、Pipeline 批量优化。