问题出现得很突然,日志倒是留得挺全。Redis 6.2 的实例每隔一段时间出现四百毫秒的延迟尖刺,和业务高峰对不上,慢查询日志里是空的,info stats 里 latest_fork_usec 有几十万。

刚开始盯着「没有开 bgsave 的副本,单个子进程承担全部落盘工作」,折腾了半个多小时,排掉了。

原因不止一个,得分开看。save 900 1 的含义是九百秒内有一次写入就落盘,业务写频繁时几乎每次检查都触发。少数情况下是fork 要复制页表,实例内存越大耗时越长,这段时间主线程被挂住。

另外,磁盘是普通云盘,RDB 写入时的 IO 争抢又放大了毛刺。

动手时先看 fork 到底花了多久

redis-cli info stats | grep -E 'latest_fork_usec|rdb_last_bgsave_status'

随后关掉定时 RDB,改为外部定时备份

redis-cli config set save ''

再往下用 bgsave 手动触发并观察耗时

redis-cli bgsave && redis-cli info persistence | grep rdb_last_bgsave_time_sec

等前面都确认过,再把持久化配置写回文件

sed -i 's/^save .*/save ""/' /etc/redis.conf && grep -n '^save' /etc/redis.conf

别只看报错消失,验证要多做一步。延迟监控上的规律性毛刺消失,latest_fork_usec 不再出现几十万的峰值,rdb_last_bgsave_status 仍然是 ok。

提醒一点。fork 的耗时和实例内存成正比,十 G 以上的实例要慎用高频 RDB;改成从库或外部工具做备份,主库只留 AOF。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189