简单来说,AOF持久化会将被执行的命令写到AOF文件的末尾,以此来记录数据发送的变化。因此,Redis只要从头到尾重新执行一次AOF文件包含的所有写命令,就可以恢复AOF文件所记录的数据集。AOF持久哈可以通过设置代码appendonly yes配置选项来打开。

文件同步:在向硬盘写入文件时,至少会发生三件事情,当调用file.write()方法(或其它编程语言里面的类似操作)对文件进行写入时,写入的内容首先会被存储到缓冲区,然后操作系统会在将来的某个时候将缓冲区存储的内容写入硬盘,而数据只有在被写入硬盘后,才算是真正地保存到了硬盘里面。用户可以通过调用file.flush()方法来请求操作系统尽快地将缓冲区存储的数据写入硬盘里面,但具体地执行写入操作仍然由系统决定。除此之外,用户还可以命令操作系统将文件同步(sync)到硬盘,同步操作会一直阻塞直到指定的文件被写入硬盘为止。当同步操作执行完毕之后,即使系统出现故障也不会低被同步的文件造成任何影响。

下表展示了appendfsync 配置选项对AOF文件的同步频率的影响。

选项 同步频率
always 每个Redis写命令都要同步写入硬盘。这样做会严重降低Redis的速度。
everysec 每秒执行一次同步,显示地将多个写命令同步到硬盘。
no 让操作系统来决定应该何时进行同步。

如果用户使用appendfsync always 选项的话,那么每个Redis写命令都会被写入硬盘,从而将发生系统崩溃时出现的数据丢失减到最少。不过遗憾的是,因为这种同步策略需要对硬盘进行大量写入,所以Redis处理命令的速度会受到硬盘性能的限制:转盘式硬盘(spinning disk)在这种同步频率下每秒只能处理大约200个写命令,而固态硬盘(solid-state drive,SSD)每秒大概也只能处理几万个写命令。

警告:固态硬盘和appendfsync always

使用固态硬盘的用户请谨慎使用appendfsync always选项,因为这个选项让Redis每次只写入一个命令,而不是像其他appendfsync选项那样一次写入多个命令,这种不断地写入少量数据的做法有可能会引发严重的写入放大(write amplification)问题,在某些环境下甚至会将固态硬盘的寿命从原来的几年降低为几个月。

为了兼顾数据安全和写入性能,用户可以考虑使用appendfsync everysec选项,让Redis以每秒一次的频率对AOF文件进行同步。Redis每秒同步一次AOF文件时的性能和不使用任何持久化特性时的性能相差无几,而通过每秒同步一次AOF文件,Redis可以保证,即使出现系统崩溃,用户也最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis还会优雅地放慢自己的速度以便适应硬盘的最大写入速度。

最后,如果用户使用appendfsync no选项,那么Redis将不对AOF文件执行任何显示的同步操作,而是由操作系统来决定应该在何时对AOF文件进行同步。这个选项在一般情况下不会对Redis的性能带来影响,但系统崩溃将导致使用这种选项的Redis服务器丢失不定数量的数据。另外,如果用户的硬盘处理写入操作的速度不够快的话,那么当缓冲区被等待写入磁盘的数据填满时,Redis的写入操作将被阻塞,并导致Redis处理命令请求的速度变慢。因为这个原因,一般来说并不推荐使用appendfsync no选项,在这里介绍了它只是为了完整列举appendfsync选项的可用的3个值。

虽然AOF持久化非常灵活地提供了多种不同的选项来满足不同应用程序对数据安全的不同要求,但AOF持久化也有缺陷:那就是AOF文件的体积大小。

results matching ""

    No results matching ""