Redis 作为一款高性能的内存数据库,其数据存储在内存中,为了防止服务器宕机或故障导致数据丢失,需要采用持久化机制将数据保存到磁盘。AOF(Append Only File,仅追加文件)就是 Redis 提供的一种重要的持久化方式。
AOF 原理
AOF 持久化通过保存 Redis 执行的写命令来记录数据库的状态。它将所有的写操作(如 SET、DEL 等)以日志的形式追加到 AOF 文件中,而读操作不进行记录。在 Redis 重启时,会读取 AOF 文件并重新执行其中的写命令,从而恢复数据库的状态。
AOF 持久化策略
Redis 为 AOF 提供了三种写磁盘的策略:
Always(每条指令保存一次):每执行一个写命令,Redis 都会立即将其同步写入磁盘,然后才返回结果给客户端。这种策略保证了数据的即时性,但在磁盘 I/O 繁忙时会阻塞 Redis 主线程,增加响应延迟。若在写入磁盘过程中出现断电或宕机,且内存写入成功,Redis 重启后通过 AOF 文件恢复数据时,可能无法恢复正在执行的这条数据。EverySecond(每秒钟保存一次):Redis 执行写操作后先写入内存和 AOF 缓冲区,然后立即返回结果,后台线程每秒将缓冲区内容写入磁盘。这种策略在断电或宕机时可能丢失最近一秒的数据。
No(不保存):Redis 写入内存成功后将写命令写入 AOF 缓冲区,至于缓冲区何时写入磁盘由操作系统决定。在这种策略下,断电或宕机时丢失的数据量由操作系统的刷盘机制决定。
AOF 持久化流程
当客户端发送写命令请求时,首先会被追加到 AOF 缓冲区。接着,根据设定的持久化策略(如 always、everysec 或 no),将缓冲区中的操作同步到磁盘的 AOF 文件中。
如果 AOF 文件大小超过了重写策略设定的值或者进行手动重写,Redis 会对 AOF 文件进行重写,以压缩文件容量。当 Redis 服务重启时,会重新加载 AOF 文件中的写操作,实现数据恢复。
AOF 文件的重写
随着时间推移,AOF 文件会因保存的写命令增多而体积增大,Redis 重启时恢复数据的时间也会变长。因此,需要对 AOF 文件进行重写以瘦身。
AOF 重写并非读取和修改原文件,而是针对数据库中键的当前值,用最少的命令来替代之前的多条命令。例如,对于对某个键的多次操作,可以用一条能恢复当前值的命令替代之前的多条命令。
Redis 在 4.0 版本后的重写,是将 RDB 的快照以二进制形式附在新的 AOF 头部,作为历史数据,替换原有的流水账操作。
重写过程中,主线程会 fork 出一个子进程来执行重写操作。这样做有两个好处:一是主进程可以继续处理客户端的命令请求;二是子进程带有数据库数据副本,避免使用锁来保证数据安全。
为了记录重写期间的新写命令,Redis 设置了 AOF 重写缓冲区。待重写完成,将缓冲区中的命令写入新的 AOF 文件,确保数据不丢失。
总结
AOF备份可靠,数据丢失概率低。AOF 文件是可读的文本,便于通过操作文件恢复误操作。AOF 持久化机制为 Redis 提供了一种较为稳健的数据备份方式,但在实际应用中,需要根据具体的业务需求和性能要求,合理选择持久化策略或结合使用 RDB 等其他持久化方式。