主库开启appendfsync always会阻塞写请求,因fsync()强制刷盘且为阻塞式系统调用,在高qps下导致主线程卡顿、延迟飙升;推荐备库启用aof(everysec)+主库仅用rdb,实现持久化成本与服务性能的合理分离。

RDB 和 AOF 同时开启时,主库写压力会显著上升,尤其在高吞吐写入场景下,AOF 的 fsync 策略(如 appendfsync always)会直接拖慢主库响应,而 fork + 写时复制本身也有内存与 CPU 开销;这不是“要不要做持久化”的问题,而是“在哪做、怎么配”更合理。
为什么主库开 appendfsync always 会卡住写请求
AOF 的 appendfsync always 表示每次写命令执行完就调用 fsync() 强制刷盘,该系统调用是阻塞式的,必须等磁盘物理写入完成才返回。在机械盘或高负载 SSD 上,单次 fsync() 可能耗时数毫秒——当 QPS 超过 1k,延迟毛刺就会明显,Redis 主线程被卡住,INFO stats 中的 latest_fork_usec 和 aof_delayed_fsync 会持续升高。
- 实际表现:客户端出现 sporadic timeout,
redis-cli --latency显示 p99 延迟跳变到 20ms+,但INFO memory显示内存使用平稳 - 替代方案:
appendfsync everysec是生产默认,它把刷盘合并到每秒一次的后台线程,主线程只做 write() 到内核缓冲区,几乎无感 - 注意:
everysec下极端断电仍可能丢失 1 秒数据,但比always的性能代价小两个数量级
备库执行 AOF 重写(bgrewriteaof)为什么更安全
备库不承担写流量,bgrewriteaof 触发时的 fork + 序列化过程不会影响线上服务;更重要的是,重写生成的新 AOF 文件可直接用于故障切换后的主库启动恢复,避免主库在压力下边写边重写导致的磁盘 I/O 饱和。
- 关键配置:备库需开启
appendonly yes和auto-aof-rewrite-percentage 100,但主库应设为appendonly no或仅保留 RDB - 验证方式:在备库执行
redis-cli info persistence | grep aof_rewrite,确认aof_rewrite_in_progress:0且aof_last_rewrite_status:ok - 风险点:若主库也开 AOF,重写期间子进程会复制当前 AOF 文件内容,而主库还在持续追加,极易触发
aof_current_size暴涨,引发连锁重写
主库只用 RDB + 备库接管 AOF 的典型配置组合
这种分工不是妥协,而是把持久化成本映射到非关键路径上:RDB 提供低开销快照,AOF 由备库异步承载,既保底又可控。
- 主库
redis.conf:注释所有save行(禁用自动 RDB),仅保留save "";关闭 AOF:appendonly no;确保stop-writes-on-bgsave-error yes(防止 RDB 失败后静默丢数据) - 备库
redis.conf:启用 RDB(如save 300 10)作为兜底,同时开启 AOF:appendonly yes,appendfsync everysec,并设置aof-rewrite-incremental-fsync yes减少重写时的 I/O 尖峰 - 同步前提:主从复制必须基于磁盘文件(即备库启动时先加载 RDB 或 AOF),否则
slaveof后无法构建完整数据集
真正容易被忽略的是:AOF 重写不是“越勤越好”,备库上若频繁触发重写(比如 auto-aof-rewrite-percentage 设太低),会导致大量短生命周期的临时 AOF 文件堆积,占用磁盘 inode;建议监控 aof_last_rewrite_time_sec 和 aof_current_rewrite_time_sec,把重写间隔稳定在 5–15 分钟区间更稳妥。










