latest_fork_usec异常飙升是fork阻塞的直接信号;该值持续超300ms表明主线程已受严重影响,需结合内核版本≥5.12、transparent_hugepage=never及裸设备协同优化。

看 INFO persistence 里的 latest_fork_usec 是否异常飙升
这是最直接的信号。Redis 主线程 fork 子进程做 RDB 或 AOF 重写时,会完全阻塞——而这个耗时就记在 latest_fork_usec 字段里。线上实例一旦该值持续超过 300000(即 300ms),就说明 fork 已开始影响服务可用性。
实操建议:
- 用
redis-cli -h {host} -p {port} INFO persistence | grep latest_fork_usec实时抓取 - 配合监控(如 Prometheus + redis_exporter)设置告警:过去 5 分钟
max(redis_fork_usec)> 400000 - 注意区分:该值突增 ≠ 磁盘慢,而是纯内存/内核操作延迟,和 SSD 关系极小
查客户端超时日志但 SLOWLOG 为空
Spring Boot 应用报 Connection failure occurred. Restarting subscription task after 5000 ms 或大量 JedisConnectionException: java.net.SocketTimeoutException,但执行 SLOWLOG GET 10 却看不到慢命令——这正是 fork 阻塞的典型特征:主线程卡死,连命令都排不上队,自然没机会进 slowlog。
实操建议:
- 不要只盯
redis.clients.jedis.exceptions.JedisConnectionException,重点比对异常时间点与latest_fork_usec峰值是否重合 - 检查 Spring Boot 日志中是否伴随
Unable to connect to Redis或连接池获取超时(如CannotGetRedisConnectionException),这类错误在 fork 阻塞期间高频出现 - 排除网络问题:用
telnet {host} {port}或redis-cli -h {host} -p {port} PING测试连通性;若 PING 都超时,大概率是主线程被 fork 卡住
确认内核版本与 transparent_hugepage 状态
fork 耗时高,90% 以上和内核行为强相关。Linux 3.10 默认开启 transparent_hugepage,它会让 fork 时页表复制开销指数级上升;而 5.12+ 内核已优化 copy_page_range 路径并默认规避 huge page 拆分——但前提是必须关掉 THP。
实操建议:
- 运行
cat /sys/kernel/mm/transparent_hugepage/enabled,输出必须是never;若为always或madvice,立刻执行echo never > /sys/kernel/mm/transparent_hugepage/enabled - 检查内核版本:
uname -r,低于5.12的建议升级到5.15+(KVM 虚拟机需确认 CPU 特性透传,如pdpe1gb) - 该设置重启失效,务必写入 systemd drop-in(如
/etc/systemd/system/disable-thp.service)或/etc/rc.local
别信“换 SSD 就能解决”这种说法
SSD 对 fork 阻塞本身几乎零改善。fork 是内核复制页表、VMA、TLB shootdown 的过程,不读写磁盘。所谓“SSD 加速 fork”,其实是掩盖了底层存储栈缺陷(如 qcow2 虚拟磁盘引发的 page fault 栈加深),让问题表现得不那么剧烈——但根因仍在内核和内存管理层面。
实操建议:
- 如果 Redis 运行在虚拟机或容器中,优先检查存储后端:避免
qcow2、thin-LVM、gp2等带文件系统层的卷;裸设备(raw block device)+ NVMe 才是有效组合 -
appendfilename和dbfilename对应的路径,不能挂载在虚拟化存储上;否则即使换 NVMe,latest_fork_usec标准差仍高 3–5 倍 - 真正起效的是三件套协同:
kernel ≥ 5.12+transparent_hugepage=never+裸设备直连;单改一项基本无效
INFO persistence、绑定 latest_fork_usec 告警、并确保内核配置不可重启失效。











