
怎么在 redis.conf 里配 appendfsync
直接改配置文件里的这一行就行:appendfsync everysec(默认值),改成 always 或 no 也只换这个词,不用加引号、不用改路径或重启以外的其他项。
注意:必须同时开启 AOF 功能,否则这个配置不生效——确认 appendonly yes 已启用。改完记得 redis-cli CONFIG REWRITE 或重启服务,CONFIG GET appendfsync 可实时验证是否生效。
别漏掉 appendonly yes,光设 appendfsync 没用改完不 reload/restart,新策略不会生效;用 CONFIG SET appendfsync everysec 是临时生效,但重启后会丢appendfsync 是全局策略,不能按 DB 或 key 粒度区分
always / everysec / no 的落盘时机和实际丢失风险
三者本质区别在于「Redis 进程把命令从内存缓冲区刷到磁盘」的触发时机不同,不是“写不写”,而是“什么时候真正落盘”:
always:每次写命令执行完,立刻调用 fsync() 强制刷盘。断电/崩溃几乎不丢数据,但每条命令都等 I/O,QPS 明显下降(尤其机械盘)everysec:命令先写进内核缓冲区,Redis 启一个后台线程,每秒 fsync() 一次。宕机最多丢 1 秒数据,吞吐和安全性平衡最好,95% 场景该选它no:只调用 write(),由操作系统决定何时 fsync()(通常几秒到几十秒不等)。性能最高,但意外掉电可能丢几分钟数据——别在非纯缓存场景用
实测过:压测写入 10k QPS 时,always 延迟常飙到 2–5ms,everysec 稳在 0.2–0.4ms,no 能压到 0.08ms 以下,但关机后发现 AOF 文件里少了近 3 秒的命令。
为什么 everysec 是默认且最稳妥的选择
它不是“折中妥协”,而是 Redis 在 Linux 内核行为、磁盘 I/O 特性、故障统计概率之间反复权衡后的工程解:
Linux 的 write() + 定期 fsync() 组合,在 ext4/xfs 上能保证每秒刷盘的可靠性,极少出现“卡住不刷”单点 Redis 故障时,1 秒数据丢失在绝大多数业务(如会话、排行榜、计数器)中可接受;真要零容忍,得上哨兵+从库+AOF+重放链路,不是靠调一个参数对比 RDB,everysec 的 AOF 恢复更可控——RDB 快照间隔外的数据全丢,而 AOF 至少保留最近 1 秒
曾有团队把生产库切到 always 后发现延迟毛刺变多,监控显示 fsync 耗时峰值超 8ms(NVMe 盘都这样),最后还是切回 everysec 并加了从库兜底。
容易被忽略的两个硬限制
再合理的策略,撞上这两个点就失效:
AOF 重写期间,appendfsync 策略会暂时降级为 no(即使你配的是 always),因为重写是子进程做的,主进程只管追加新命令,此时新命令只 write() 不 fsync() —— 所以别在重写高峰做关键数据写入如果磁盘满、AOF 文件不可写,Redis 默认会停止写操作并报错 OOM command not allowed when used memory > ‘maxmemory’.(实际是 I/O 错误被掩盖了),日志里找 Can’t open the append-only file 才是真因
配置里加 auto-aof-rewrite-min-size 64mb 和 auto-aof-rewrite-percentage 100 能减少重写频率,但无法消除它——这点比参数本身还重要。

评论(0)