LATENCY 监控:捕捉 Redis 卡顿的延迟事件
SLOWLOG 只能抓"某条命令执行得慢",但生产上另一类更隐蔽的卡顿来自命令之外:fork、AOF 刷盘、淘汰循环、碎片整理,这些系统级动作不在任何一条命令里,slowlog 全然无感。LATENCY 监控以"延迟事件"为单位记录这类尖刺,并自带一份分析报告。本文以 Redis 7 为准,讲清事件模型、四个子命令的用法和 DOCTOR 报告的读法。
一、它与 SLOWLOG 的分工
两者是互补关系,不是替代关系:
| 维度 | SLOWLOG | LATENCY 监控 |
| --- | --- | --- |
| 记录对象 | 单条慢命令 | 系统级延迟事件 |
| 阈值单位 | 微秒 | 毫秒 |
| 是否记录命令参数 | 是 | 否 |
| 典型问题 | 谁在执行慢命令 | 为什么所有命令都变慢 |
一句经验法则:批量请求同时慢、P99 抖动,查 LATENCY。两者都干净,再往网络、客户端和操作系统层找。
监控记录的延迟是主线程视角的墙钟时间:不管是命令在执行、在等锁、还是在等磁盘刷盘,只要超过阈值就会被记为一笔。这个口径与客户端体感到的"命令变慢"高度一致,也是它比 SLOWLOG 更贴近业务感受的原因。
两者还有一个数量级上的差别容易被忽略。SLOWLOG 的阈值单位是微秒,10 毫秒已经算"慢";LATENCY 的阈值单位是毫秒,默认建议 100 毫秒起。这意味着两者关注的不是同一类问题:SLOWLOG 抓的是"某条命令本身要几十毫秒",量级在毫秒到秒之间;LATENCY 抓的是"整个实例卡了超过 100 毫秒",量级在百毫秒到秒之间。把 latency-monitor-threshold 设成 1 毫秒,等于让 LATENCY 退化成一个大号的 SLOWLOG,记录的绝大多数是正常波动,真正的问题反而被淹没。
二、开启与事件类型
LATENCY 监控默认关闭,latency-monitor-threshold 默认 0。设为非零毫秒数后,任何超过该阈值的"事件"都会被记录:
CONFIG SET latency-monitor-threshold 100 # 单位毫秒
Redis 7 记录的主要事件类型:
command/fast-command:普通命令与 O(1)/O(log N) 快速命令的执行耗时;fork:BGSAVE、AOF 重写时的 fork 耗时,与实例内存大小正相关;aof-fsync-always:appendfsync always策略下每次写都刷盘的耗时;aof-write、aof-write-pending-fsync、aof-write-active-child、aof-write-alone:AOF 写入被拖慢的几种成因,分别对应"有 fsync 待处理""写发生在子进程期间""写是独占的";aof-rewrite-diff-write、aof-rename:重写期间写增量文件、以及重命名文件的耗时;expire-cycle、eviction-cycle、eviction-del:过期扫描、淘汰循环、以及删除被淘汰 key 本身的耗时;rdb-unlink-temp-file:删除 RDB 临时文件的耗时;active-defrag-cycle:碎片整理周期占用超预期。
两点补充说明。expire-cycle 指主动过期扫描单次耗时过长:过期周期每轮只花固定时间抽查 key,过期 key 密集堆积时单轮会被拉满;eviction-cycle 与 eviction-del 则是内存触顶后淘汰逻辑的耗时——前者看"淘汰决策与循环",后者看"真正删除 key 的释放动作",频繁出现说明容量已经不足,属于要扩容的信号。
每个事件类型各自维护一条时序记录(默认最多保留 160 个采样点),记录"何时发生、持续多久"。
三、四个子命令
LATENCY LATEST # 每类事件最近一次的延迟
LATENCY HISTORY fork # 某类事件的历史时序
LATENCY GRAPH fork # ASCII 时序图
LATENCY DOCTOR # 人类可读的综合诊断报告
LATENCY RESET # 清空历史
LATENCY LATEST 的输出每行四列:
127.0.0.1:6379> LATENCY LATEST
1) 1) "fork"
2) (integer) 1769300000 # 事件发生的时间戳
3) (integer) 352 # 最近一次延迟,毫秒
4) (integer) 512 # 该事件的历史最大延迟,毫秒
LATENCY GRAPH 用字符画出时间轴,直观看到毛刺集中在什么时段;LATENCY HISTORY 输出原始采样点,适合接入脚本做告警。日常巡检看 LATEST,复盘看 HISTORY 与 GRAPH。LATENCY DOCTOR 的报告结构是总览结论在前、逐事件展开在中、修复建议在后,把整段文本贴进工单或告警通知,比截图监控图更能让值班同事快速理解。
LATENCY GRAPH 的输出值得熟悉一下,它的信息密度比想象中高。格式是首行给出本次峰值与历史峰值,随后每个刻度一行,右侧用字符画出该采样点的高度:
127.0.0.1:6379> LATENCY GRAPH fork
fork - high 352 ms, low 2 ms (all time high 352 ms)
--------------------------------------------------------------------------------
352 ms | #
176 ms |****************#************************************************
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
纵轴是延迟刻度,横轴是采样序号,* 是该刻度以下的部分,# 标记超出该刻度的采样点。上例只有一处 # 顶到 352 ms,其余采样都在 176 ms 线以下——这种"孤峰"形态通常是某一次 BGSAVE 的 fork,而如果形态是"持续的锯齿",说明每一轮 fork 都慢,问题在实例规模而不是偶发因素。形态比具体数字更能反映性质,这也是 GRAPH 在复盘时比 HISTORY 更好用的原因。
采集 LATENCY LATEST 时要注意一个陷阱:它只给出每类事件的"最近一次"与"历史最大",如果连续两次采集之间发生了多次同类事件,中间的过程会丢失。要完整记录必须自己按秒轮询 LATENCY HISTORY 并与上次采集的最后一个时间戳比对,取出新增部分。简单地把 LATEST 存下来做趋势图,得到的曲线会是"最近一次的值",而不是"该时间段内的最大值",容易产生误判。
四、DOCTOR 报告怎么读
LATENCY DOCTOR 把所有事件汇总成一段诊断文本,直接给出建议,例如:检测到 fork 延迟高,说明实例内存偏大或写时复制严重,建议降低实例内存或单独一个从库做持久化;检测到 aof-write-active-child,指向 AOF 写盘与子进程并存导致 IO 争抢,建议检查磁盘负载或错开重写时间。它的建议是通用启发式,方向准确,但具体归因要再结合两处证据:
INFO memory的used_memory与mem_fragmentation_ratio,对应 fork 与淘汰类事件;INFO persistence的aof_delayed_fsync计数、current_cow_size,以及操作系统侧的磁盘 util 与 swap 使用,对应 AOF 与系统层事件。
提示:把
LATENCY LATEST接入定时采集,任何事件的最大延迟超过业务容忍值就告警,比事后翻日志高效得多。
五、一次完整排障路径
线上收到"P99 抖动"类告警时,按这个顺序走一遍:
LATENCY LATEST看最近哪类事件在冒头,锁定事件类型与发生时间点;LATENCY HISTORY与LATENCY GRAPH拉长时间轴,确认毛刺是周期性(比如整点的 AOF 重写)还是随机分布;- 按事件类型分支定位:
fork查实例内存与持久化计划,aof-*查磁盘负载与刷盘配置,eviction-*查内存水位,fast-command/command转去 SLOWLOG 找具体命令; - 排除环境噪声:用
redis-cli --intrinsic-latency 60在服务器本地采样 60 秒,量出系统自身的调度延迟基线;基线本身就有几十毫秒毛刺时,问题在宿主机(超售、NUMA、透明大页),不在 Redis 命令路径; - 治理后保留
LATENCY LATEST的定时采集,验证毛刺确实消失再关告警。
这条路径的价值在于分支清晰:事件类型直接指向责任层——内核、磁盘、内存还是命令本身,避免一上来就盲目重启换节点。
常见坑 / 最佳实践
- 默认是关闭的,上线先打开。
CONFIG SET latency-monitor-threshold 100并写入配置文件;阈值单位是毫秒,别按 SLOWLOG 的微秒习惯填 10000。 - 阈值过低会产生大量噪音。 100ms 左右起步,观察一周后再按需调整;设成 1ms 会记录到海量正常波动,反而淹没真正的毛刺。
LATENCY RESET会清空历史。 想保留现场就先LATEST和HISTORY导出,别在排障脚本里随手 RESET。- fork 事件高频出现不是延迟 bug,是容量问题。 实例内存越大 fork 越慢,根治靠拆实例、控制单实例内存在 10GB 以内量级。
eviction-cycle事件频繁说明内存不够用了。 这时优先扩容或调淘汰策略,而不是纠结毫秒数。
小结
- LATENCY 监控补齐 SLOWLOG 的盲区,记录 fork、AOF 刷盘、淘汰循环等系统级延迟事件。
- 默认关闭,
latency-monitor-threshold单位毫秒,生产建议 100ms 起步。 LATEST看现状、HISTORY/GRAPH看时序、DOCTOR给诊断,巡检告警挂LATEST。- DOCTOR 的建议指方向,最终归因要结合
INFO memory、INFO persistence与操作系统指标。 - 与 SLOWLOG 的分工:单条慢查命令,批量抖动查事件。
- 点赞
- 收藏
- 关注作者
评论(0)