《Java后端知识体系系列》之Redis持久化AOF(一)

最近一直在看《Redis的设计与实现》一书,做的一些总结吧,以便以后自己复习Redis的知识。

一、介绍

除了RDB持久化功能之外,Redis还提供了AOF(Append Only File)持久化功能。与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的。
例如:

redis>SET msg "hello"
OK
redis>SADD fruits "apple" "banana" "cherry"
OK
redis>RPUSH numbers 128 256 512
(integer) 3

RDB持久化保存数据库的方法是将msg、fruits、numbers三个键的键值对保存到RDB文件中,而AOF持久化保存数据库的方法是将服务器执行的SET、SADD、RPUSH三个命令保存到AOF文件中。
被写入AOF文件的所有命令都是以Redis的命令请求协议格式保存的,因为Redis的命令请求协议是纯文本格式。

二、实现

AOF持久化功能的实现可以分为:命令追加(append)、文件写入、文件同步(sync)三个步骤。

2.1 命令追加

当AOF持久化功能处于打开状态时,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区的末尾:

struct redisServer{
//..
//AOF缓冲区
sds aof_buf;
//..
};

例如:如果执行SET KEY VALUE

redis>SET KEY VALUE
OK

那么服务器在执行SET命令之后,会将一下协议内容追加到aof_buf缓冲区末尾:

*3\r\n$3\r\nSET\r\n$3\r\nKEY\r\n$5\r\nVALUE\r\n
2.2 AOF文件的写入和同步

Redis的服务器进程就是一个事件循环,这个循环中的文件事件负责接收哭护短的命令请求,以及向客户端发送命令回复,而时间时间则负责执行像serverCorn函数这样需要定时运行的函数。
因为服务器在处理文件事件时可能会执行写命令,使得一些内容被追加到aof_buf缓冲区里面,所以在服务器每次结束一个事件循环之前,它都会调用flushAppendOnlyFile函数,考虑是否将aof_buf缓冲区的内容写入到AOF文件里面,这个过程用伪代码表示为:

def eventLoop():
while True:
#处理文件事件,接收命令请求以及发送命令回复
#处理命令请求时可能会有新内容被追加到aof_buf缓冲区中
processFileEvents()
#处理时间时间
processTimeEvents()
#考虑是否将aof_buf中的内容写入和保存到AOF文件里面
flushAppendOnlyFile()

flushAppendOnlyFile函数的行为由服务器配置的appendfsync选项的值来决定:
appendfsync选项的值分为:always、everysec、no

  • always:将aof_buf缓冲区的所有内容写入并同步到AOF文件
  • everysec:将aof_buf缓冲区中所有的内容写入到AOF文件,如果上次同步AOF文件的时间距离现在超过一秒钟,那么再次对AOF文件进行同步,并且这个同步操作是由一个线程专门负责的。
  • no:将aof_buf缓冲区中所有的内容写入到AOF文件,但不对AOF文件进行同步,何时同步由操作系统决定。
    为了提高文件的写入效率,在现代操作系统中,当用户调用write函数,将一些数据写入到文件的时候,操作系统通常会将写入数据暂时保存在一个内存缓冲区里面,等到缓冲区被填满,或者超过了指定的时间限定时,才将缓冲区的数据同步到磁盘文件中。

这样做虽然提高了效率,但是如果计算机发生停机,那么保存在内存缓冲区里面的写入数据会丢失。
为此,系统提供了fsync和fdatasync两个同步函数,它们可以强制让操作系统将缓冲区中的数据写入到磁盘里面,从而确保写入数据的安全性。

2.3 区别
  1. 当appendfsync的值为always时,服务器在每个事件循环都要将aof_buf缓冲区中所有的内容写入到AOF文件,并且同步AOF文件,所以always的效率时三个选项中最慢的一个,但是从安全性上讲,always也是最安全的,即使发生停机,AOF持久化也只会丢失一个事件循环中所产生的命令数据。
  2. 当appendfsync的值为everysec时,服务器在每个事件循环都要讲aof_buf缓冲区的所有内容写入到AOF文件,并且每隔一秒就要在子线程中对AOF文件进行一次同步。从效率上来讲everysec模式足够快,并且即使发生停机也只会丢失一秒钟的命令数据。
  3. 当appendfsync的值为no时,服务器在每个事件循环都要讲aof_buf缓冲区中所有的内容写入到AOF文件,至于合适对AOF文件进行同步,则由操作系统控制。所以该模式下AOF文件写入速度是最快的,但是单次同步时间是最长的。并且no模式会丢失上次同步AOF文件之后所有的命令数据。

知之为知之,不知为不知,是知也!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值