appendfsync always并不绝对安全,因存在三重断层:进程可能在write后、fsync前被SIGKILL终止;fsync后数据仍可能滞留于内核page cache或SSD写缓存;硬盘控制器写缓存若未禁用(如未执行hdparm -W0),数据仍未落盘。

appendfsync always 为什么实际并不“绝对安全”
很多人看到 appendfsync always 就默认“写完即落盘、绝不丢数据”,但生产环境里它既不能真正避免丢失,又会拖垮吞吐。根本原因在于三处断层:write() 到 fsync() 之间进程可能被 SIGKILL 杀死;fsync() 调用后,Linux page cache 或 SSD 写缓存仍可能未真正刷入物理介质;即使前两步都走完,硬盘控制器若没禁用写缓存(比如未执行 hdparm -W0 /dev/sda),数据还在设备缓存里。
实测中,appendfsync always 下 Redis 的 SET 吞吐会跌到约 58k req/s,比 everysec 低 5–10 倍。更关键的是:它不解决 RPO(恢复点目标)为 0 的需求——真要零丢失,得配 WAL 日志 + 同步复制 + 硬件级掉电保护,不是单靠一个配置项。
appendfsync everysec 是大多数业务的合理起点
appendfsync everysec 不是“每 1000ms 精确触发一次”,而是由 Redis 主循环中的定时器驱动。这意味着:
- 若主线程卡住(如执行
KEYS *、序列化超大 value、或 GC 停顿),刷盘可能延迟数秒 - 后台 AOF 重写(
bgrewriteaof)期间,新命令仍追加到旧 AOF 文件,everysec对这部分依然生效 - 当磁盘 I/O 延迟突增(例如 RAID 卡电池学习、SSD GC),Redis 默认会临时降级为
always刷盘——这个行为由no-appendfsync-on-rewrite no控制,别误以为关了它就“稳了”
如果你的应用能接受秒级 RPO(比如用户发帖失败后前端自动重试),everysec 就够用。它在多数压测中维持 58k+ req/s 吞吐,同时把数据丢失控制在 1 秒内。
appendfsync no 只适合两类明确场景
appendfsync no 表示完全交由操作系统决定刷盘时机(通常 30–60 秒),它不是“性能优化技巧”,而是风险兜底方案。仅适用于:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 纯缓存型部署:AOF 仅用于故障后快速重建热 key 分布,不要求数据精确恢复(例如 session 存储 + 前端 token 续期兜底)
- 写压极高且磁盘 I/O 已成瓶颈的节点:比如每秒写入 50k+ 小命令,
iostat -x 1显示%util > 90%持续存在
用 no 必须同步做两件事:save 配置项必须全关(避免 BGSAVE fork 加剧延迟),且必须有外部补位机制——比如应用层双写 MySQL、或写入 Kafka 消息队列。否则宕机就是全量丢失,没有中间态。
混合持久化下 fsync 策略如何协同 RDB
Redis 支持 RDB + AOF 混合使用(aof-use-rdb-preamble yes),此时 AOF 文件开头是 RDB 格式快照,后面才是增量命令。但注意:appendfsync 仍然只控制 AOF 日志部分的刷盘行为,RDB 的 save 触发逻辑(如 save 60 10000)和刷盘时机完全独立。
这意味着:
- RDB 快照本身不依赖
fsync策略,它的可靠性取决于fork和子进程写文件是否成功 - AOF 增量部分仍按你设的
appendfsync执行,所以混合模式下仍需谨慎选值 - 若启用混合模式又设
appendfsync no,AOF 文件头部的 RDB 快照是可靠的,但尾部日志可能丢失大量增量——恢复时会回到快照时刻,而非最后写入时刻
真正容易被忽略的是:fsync 策略不是孤立参数,它和 no-appendfsync-on-rewrite、auto-aof-rewrite-percentage、甚至 Linux 的 vm.dirty_ratio 都存在隐式耦合。调优前务必在 staging 环境用 redis-benchmark -t set -n 1000000 -c 50 实测吞吐与延迟分布,而不是只看文档里的“推荐值”。


















