根本原因是fork子进程时操作系统拷贝页表耗时,尤其内存大、页表复杂或启用透明大页(thp)时可达数百毫秒;应优先禁用thp(设为never并验证smaps无2048kb页),再调优rdb/aof策略及排查io、swap、调度问题。

Redis持久化时CPU飙升、响应延迟突增怎么办
根本原因不是RDB或AOF本身慢,而是fork子进程时,操作系统需要拷贝父进程页表——当内存大、页表复杂,或启用了透明大页(THP)时,fork耗时从毫秒级跳到几百毫秒,直接卡住主线程响应。
实操上优先关THP,再调优持久化策略:
-
/sys/kernel/mm/transparent_hugepage/enabled必须设为never(不只是madvice);临时生效用echo never > /sys/kernel/mm/transparent_hugepage/enabled,但要写进/etc/rc.local或systemd服务确保重启不回退 - RDB触发频率别依赖
save 900 1这类宽松条件,大实例建议关自动RDB,改用redis-cli --rdb /path/dump.rdb在低峰期手动触发 - AOF重写期间同样fork,所以
auto-aof-rewrite-percentage别设太高(如300),避免重写太频繁;同时确保aof-rewrite-incremental-fsync为yes,让重写时分批刷盘,减少单次I/O压力
检查THP是否真关了,别被cat /sys/kernel/mm/transparent_hugepage/enabled骗
输出显示[never]只是当前状态,不代表内核没在后台悄悄启用。真实影响看/proc/<pid>/smaps</pid>里MMUPageSize和MMUPFPageSize字段:如果大量页显示2048 kB,说明THP仍在生效。
验证方法:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 先找Redis主进程PID:
ps aux | grep redis-server - 查它的smaps:
grep -i "mmupage\|mmupf" /proc/<pid>/smaps | head -10</pid> - 正常应全是
4 kB;若混有2048 kB,说明THP没彻底禁用,需检查是否被其他服务(如MySQL、Java)的启动脚本又打开了
CONFIG SET save ""能立刻停掉RDB持久化吗
不能。这个命令只清空save配置项,但不会终止正在执行的RDB子进程,也不会阻止已排队的BGSAVE任务。更危险的是,它会让Redis彻底失去RDB快照能力——下次崩溃就只能靠AOF恢复,而AOF重写失败或损坏会导致数据不可逆丢失。
安全做法是:
- 用
redis-cli BGREWRITEAOF确保AOF处于健康状态后再操作 - 真正要停RDB,改
redis.conf里的save行为空,然后CONFIG REWRITE落盘 +CONFIG RELOAD(注意:这会丢弃未保存的CONFIG SET临时配置) - 生产环境不建议完全关RDB,至少保留一个低频兜底项,比如
save 3600 1(1小时1个key变更就触发)
关闭THP后Redis延迟毛刺还存在?重点查这三处
THP只是常见诱因,不是唯一元凶。以下情况也会导致类似毛刺,且容易被忽略:
- 磁盘I/O饱和:
iostat -x 1看%util是否持续>90%,特别是AOF重写+RDB同时发生时,两路大文件写入会争抢IO带宽 - 内存swap:
free -h看SwapUsed是否非零,Redis一旦swap,fork延迟会指数级增长;必须保证vm.swappiness=1且maxmemory留10%余量 - Linux CFS调度器干扰:Redis进程优先级被压低,
chrt -a -p <pid></pid>确认是SCHED_OTHER,建议用chrt -r 1 redis-server启动,避免周期性调度延迟
THP关了只是拆了引信,但炸药还在不在,得挨个摸排IO、内存、调度这三个物理层。










