赞
踩
目录
除了RDB持久化功能之外,Redis还提供了AOF (Append Only File)持久化功能。
与快照持久化相比,AOF 持久化的实时性更好,因此已成为主流的持久化方案。默认情况下 Redis 没有开启 AOF(append only file)方式的持久化,可以通过 appendonly 参数开启:
appendonly yes
与 RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存 Redis服务器所执行的写命令来记录数据库状态的,如图
举个例子,如果我们对空白的数据库执行以下写命令,那么数据库中将包含三个键 值对:
RDB持久化保存数据库状态的方法是将msg、fruits、numbers三个键的键值对保 存到RDB文件中,而AOF持久化保存数据库状态的方法则是将服务器执行的SET、ADD、 RPUSH三个命令保存到AOF文件中。
被写入AOF文件的所有命令都是以Redis的命令请求协议格式保存的,因为Redis的命令请求协议是纯文本格式,所以我们可以直接打开一个AOF文件,观察里面的内容。
例如,对于之前执行的三个写命令来说,服务器将产生包含以下内容的AOF文件:
在这个AOF文件里面,除了用于指定数据库的SELECT命令是服务器自动添加的之外, 其他都是我们之前通过客户端发送的命令。
服务器在启动时,可以通过载入和执行AOF文件中保存的命令来还原服务器关闭之前 的数据库状态
AOF持久化功能的实现可以分为命令追加(append)、文件写入、文件同步(sync)三 个步骤。
当AOF持久化功能处于打开状态时,服务器在执行完一个写命令之后,会以协议格式 将被执行的写命令追加到服务器状态的aof_buf缓冲区的末尾:
举个例子,如果客户端向服务器发送以下命令:
那么服务器在执行这个SET命令之后,会将以下协议内容追加到aof_buf缓冲区的 末尾:
以上就是AOF持久化的命令追加步骤的实现原理。
当 Redis 收到客户端修改指令后,会先进行参数校验、逻辑处理,如果没问题,就 立即 将该指令文本 存储 到 AOF 日志中,也就是说,先执行指令再将日志存盘。这一点不同于 MySQL
、LevelDB
、HBase
等存储引擎,如果我们先存储日志再做逻辑处理,这样就可以保证即使宕机了,我们仍然可以通过之前保存的日志恢复到之前的数据状态,但是 Redis 为什么没有这么做呢?
我甚至觉得没有什么特别的原因。仅仅是因为,由于AOF文件会比较大,为了避免写入无效指令(错误指令),必须先做指令检查?如何检查,只能先执行了。因为语法级别检查并不能保证指令的有效性,比如删除一个不存在的key。而MySQL这种是因为它本身就维护了所有的表的信息,所以可以语法检查后过滤掉大部分无效指令直接记录日志,然后再执行。
AOF 日志是以文件的形式存在的,当程序对 AOF 日志文件进行写操作时,实际上是将内容写到了内核为文件描述符分配的一个内存缓存中,然后内核会异步将脏数据刷回到磁盘的。
就像我们 上方第四步 描述的那样,我们需要借助 glibc
提供的 fsync(int fd)
函数来讲指定的文件内容 强制从内核缓存刷到磁盘。但 "强制开车" 仍然是一个很消耗资源的一个过程,需要 "节制"!通常来说,生产环境的服务器,Redis 每隔 1s 左右执行一次 fsync
操作就可以了。
Redis 同样也提供了另外两种策略,一个是 永不 fsync
,来让操作系统来决定合适同步磁盘,很不安全,另一个是 来一个指令就 fsync
一次,非常慢。但是在生产环境基本不会使用,了解一下即可。
Redis的服务器进程就是一个事件循环(loop), 这个循环中的文件事件负责接收客户端 的命令请求,以及向客户端发送命令回复,而时间事件则负责执行像serverCron函数这 样需要定时运行的函数。
因为服务器在处理文件事件时可能会执行写命令,使得一些内容被追加到aof_buf缓冲 区里面,所以在服务器每次结束一个事件循环之前,它都会调用flushAppendOnlyFile函 数,考虑是否需要将aof_buf缓冲区中的内容写入和保存到AOF文件里面,这个过程可 以用以下伪代码表示:
flushAppendOnlyFile函数的行为由服务器配置的appendfsync选项的值来决 定,各个不同值产生的行为如表
如果用户没有主动为appendfsync选项设置值,那么appendfsync选项的默认值 为everysec, 关于appendfsync选项的更多信息,请参考Redis项目附带的示例配置 文件redis.conf。
为了提高文件的写入效率,在现代操作系统中,当用户调用write函数,将一些 数据写入到文件的时候,操作系统通常会将写入数据暂时保存在一个内存缓冲区里面, 等到缓冲区的空间被填满、或者超过了指定的时限之后,才真正地将缓冲区中的数据写 入到磁盘里面。
这种做法虽然提高了效率,但也为写
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。