Redis的AOF机制其实挺复杂,但我试着讲得简单点,帮你理解它到底怎么工作的
- 问答
- 2025-12-23 17:55:07
- 3
想象一下,你有一个特别好的朋友,他记忆力超群,但为了万无一失,他有个习惯:每次和你约定什么事情,他不仅记在脑子里,还会立刻写进一个随身带的小本本里,这个本本,就是Redis的AOF(Append Only File,只追加文件)。
AOF的核心:记下每一步操作
Redis平时会把数据都放在内存里,这样读写速度飞快,但内存有个问题,一断电或者重启,里面的数据就全没了,为了解决这个问题,Redis提供了两种主要的持久化方式,AOF就是其中之一(另一种是RDB,可以理解为给内存数据拍快照)。
AOF的方式非常直白:它不是去记录某个瞬间数据库里有什么,而是记录下所有会改变数据的操作命令。
- 你在客户端输入
set name 小王,Redis执行完后,会把这个命令追加到AOF文件的末尾。 - 你又输入
sadd fruits apple banana,这个命令也会被追加进去。 - 你再输入
del name,删除命令同样被追加。
这样,这个AOF文件就变成了一本按时间顺序记录的、详尽的“操作日记”,当Redis服务器重启的时候,它不需要去回忆之前存了什么,它只需要把这个日记本从头到尾、一字不差地重新执行一遍,就能完美地恢复到关机前的状态。
写日记的时机:三种谨慎程度
直接把命令写到日记本里,这个动作本身也需要时间,如果每写一个命令就立刻强迫症似的去翻本子、拿笔、写完再合上,那整个人的效率(也就是Redis的性能)肯定会受影响,但如果老是想着“等会儿再一起写”,万一中途出意外,就可能丢失最近的记忆。
Redis给了我们三种写日记的策略,让你在安全性和性能之间做权衡:
-
always(总是):最安全,但也最慢,每次有写命令进来,Redis在执行完后,立刻强制把命令写入AOF文件,并且要求操作系统真正把数据写到磁盘上(这个过程叫
fsync),这样做能保证即使系统突然崩溃,最多也只丢失一个命令,但因为频繁的磁盘操作,性能开销最大。 -
everysec(每秒):折中方案,也是默认推荐,Redis会每隔一秒钟,把这一秒内积累的所有写命令批量写入一次AOF文件,这样即使上一秒刚写完,下一秒系统就崩溃,也只会丢失大概一秒钟的数据,在安全和性能之间取得了很好的平衡。
-
no(不主动同步):最不安全,但理论上最快,Redis只负责把命令写到操作系统内核的缓存区里,然后就返回了,至于操作系统什么时候真正把缓存区里的数据写入磁盘,Redis不管,这样性能最好,但如果系统崩溃,缓存区里的数据就没了,丢失的数据量可能很大。
你可以根据你的业务需求来选择,如果数据极其重要,一点都不能丢,那就用always,哪怕慢点,如果可以容忍一秒的数据丢失,那用默认的everysec就非常好。

日记本太厚了怎么办?AOF重写
如果Redis服务器连续运行很久,这个AOF日记本会变得非常非常厚,里面可能记录了成千上万个命令,比如一个计数器被反复修改了10000次,那么AOF文件里就会有10000条incr命令,但最终这个计数器的值,其实只取决于最后一次操作,前面9999条记录都是“废话”,白白占用了空间,并且在重启恢复时,重放这10000条命令也会非常慢。
为了解决这个问题,AOF提供了一个“整理日记本”的功能,叫做 AOF重写。
重写的原理非常巧妙:它不是去分析现有的那个巨大的AOF文件,而是直接根据当前数据库里的数据状态,反向生成一个全新的、最精简的AOF文件。
还是刚才计数器的例子,当前数据库里这个计数器的值是10000,那么重写时,Redis会直接生成一条命令 set counter 10000 写入新的AOF文件,对于集合、列表等复杂数据类型也是同理,它会用最少的命令来重现当前的数据。
这个新生成的AOF文件,体积会小很多,并且包含恢复数据所需的最小命令集,重写完成后,Redis会用这个新的、精炼的AOF文件替换掉旧的、臃肿的文件。

重写过程会阻塞服务吗?
重写是一个比较耗时的I/O操作,如果它把主进程完全堵住,那Redis就无法处理客户端的请求了,所以Redis很聪明地使用了 后台重写(也叫BgRewrite)。
具体做法是:主进程会fork出一个子进程,这个子进程会拥有和主进程完全一样的数据副本,由这个子进程去安心地、慢慢地生成新的AOF文件,而主进程可以继续正常处理客户端的命令,完全不受影响。
这里有个问题:在子进程创建新AOF文件的过程中,主进程还在接收新的写命令,这些新命令会导致当前数据库的数据和子进程开始工作时那个副本的数据不一致。
怎么办?Redis的解决方案是:在主进程fork出子进程后,它会同时把新接收到的写命令追加到现有的AOF文件(以防重写失败)的同时,也写入到一个特殊的“重写缓冲区”,当子进程完成了新AOF文件的创建后,主进程会把这个重写缓冲区里的所有命令追加到新的AOF文件中,这样,新的AOF文件就包含了重写开始那一刻的数据状态,以及重写过程中所有的新变更,原子地替换旧文件即可。
总结一下
Redis的AOF机制就像一个聪明的秘书:
- 记录:忠实地用“写日记”(追加文件)的方式记录每一个写命令。
- 策略:提供三种同步策略(always, everysec, no),让你在数据安全性和写入性能之间做选择。
- 瘦身:通过“重写”机制,定期根据当前数据生成最精简的日记,解决文件膨胀和恢复慢的问题。
- 优化:重写放在后台由子进程完成,不影响主进程正常工作,并通过缓冲区保证数据一致性。
通过这一套组合拳,AOF在提供很高数据安全性的同时,也尽可能地减少了对Redis高性能的影响。
本文由盈壮于2025-12-23发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/67054.html
