Redis latency-monitor 能抓到 fsync 延迟,但需手动启用 latency:fsync 事件并设置合理阈值;仅主线程 AOF append 的 fsync 可被监控,RDB/AOF rewrite 子进程的 fsync 不计入;延迟高未必磁盘忙,可能受文件系统、脏页策略或容器 SELinux 标签影响。

Redis latency-monitor 能不能直接抓到 fsync 延迟
能,但得配对用——latency-monitor 本身不区分延迟来源,它只记录事件耗时;真正把 fsync 拉进监控视野的,是 latency-monitor-threshold 配合 latency monitor 的事件类型识别。默认它不监控 fsync,必须手动开启对应事件。
-
latency-monitor-threshold设太低(比如 1ms),会高频打点,影响性能;设太高(比如 100ms),fsync慢了你也收不到告警 - Redis 6+ 默认开启
latency:command和latency:slowlog,但latency:fork和latency:fsync是关闭的,要显式启用 - 启用方式不是改配置文件就完事——得用
CONFIG SET同时打开阈值和事件:先CONFIG SET latency-monitor-threshold 5,再CONFIG SET latency-events "command,fsync"
怎么确认 fsync 真的被 latency-monitor 捕获到了
靠 LATENCY LATEST 和 LATENCY HISTORY fsync。前者只返回最近一次超阈值的 fsync 记录,后者能看过去 128 条(固定长度),适合排查偶发卡顿。
- 如果
LATENCY HISTORY fsync返回空,说明要么没触发超阈值,要么fsync事件根本没开——检查CONFIG GET latency-events输出里有没有fsync - 注意:RDB 快照期间的
fsync来自子进程,AOF rewrite 期间的fsync也来自子进程,但 latency-monitor 只在主线程上下文记录;所以只有 AOF append 模式下主线程调用的fsync才会被捕获(即appendfsync always或everysec的刷盘时刻) -
appendfsync no时,主线程从不调fsync,LATENCY HISTORY fsync永远为空——这不是 bug,是设计如此
为什么看到 fsync 延迟高,但磁盘 I/O 并不忙
常见于使用 ext4 + data=ordered 模式、或 XFS + barrier=1 的文件系统,fsync 不仅刷数据,还要等日志提交完成,而日志落盘可能被其他进程阻塞,或受存储设备写缓存策略干扰。
- Linux 的
vm.dirty_ratio和vm.dirty_background_ratio如果设得过高,内核会攒大量脏页,导致fsync时被迫回写,耗时陡增 - NVMe 盘开启 Write Cache 但未配
barrier,fsync可能假快真慢——实际数据还在易失缓存里,断电即丢;而 latency-monitor 测到的是系统调用返回时间,不是数据落盘时间 - 容器环境(如 Docker)挂载卷时用了
:z或:ZSELinux 标签,可能引入额外元数据同步开销,也会抬高fsync耗时
生产环境开启 fsync 监控要注意什么
别在高峰期临时开,尤其别设 1ms 阈值——latency-monitor 的采样本身有开销,高频触发会挤占主线程 CPU,反而加剧延迟。
- 建议阈值设为预期
fsyncp99 的 1.5 倍,比如实测 p99 是 8ms,就设latency-monitor-threshold 12 - 避免在
appendfsync always场景下长期开启——每条写命令都触发fsync,采样密度太高,容易掩盖真实毛刺 -
LATENCY RESET fsync清空历史前,先用LATENCY GRAPH fsync看一眼趋势,否则可能漏掉正在发生的持续性升高
fsync 延迟不是独立指标,它和 AOF 缓冲区大小、磁盘调度器、内核版本强耦合——看到异常值,别急着调 Redis,先查 iostat -x 1 和 cat /proc/sys/vm/dirty*。

















