什么是Redis持久化?
Redis是键值对的内存数据库,它将数据存储在内存里。客户端发送命令到服务器,再由服务器到内存里查找数据。
一旦Redis服务器进程退出,存储在内存里的数据就会丢失。
为了解决这个问题,Redis提供了持久化机制,即将数据保存到磁盘里,以便Redis服务器进程初始化或重启后重新加载数据,避免数据丢失。
Redis提供两种持久化方案,分别是RDB(Redis DataBase)和AOF(Append Only File)。
RDB持久化RDB采用快照的方式来实现持久化,把数据库数据保存到RDB文件里,也可以通过RDB文件还原数据库数据。
开启RDB持久化的方式RBD是Redis默认的持久化方案,可以通过三种方式来生成RDB文件:SAVE、BGSAVE和自动触发,其中前两种是主动操作,后一种是被动操作,由Redis服务器控制。
SAVESAVE命令会阻塞Redis服务器进程,直到RDB文件创建完成,在服务器进程阻塞期间,服务器不能处理任何命令请求。
redis> Save // 等待直到RDB文件创建完成 OK BGSAVE和SAVE命令直接阻塞服务器进程不同,BGSAVE命令会fork一个子进程来负责创建RDB文件,服务器进程继续处理命令请求。
redis> BGSAVE // fork子进程,并由子进程创建RDB文件 Background saving started 自动触发Redis允许用户通过设置服务器配置的save选项,让服务器每隔一段时间自动执行一次BGSAVE命令。用户可以通过save选项设置多个条件,只要满足其中任意一个条件,服务器就会执行BGSAVE命令。
save 900 1 // 服务器在900秒内,至少1次修改 save 300 10 // 服务器在300秒内,至少10次修改 save 60 10000 // 服务器在60秒内,至少10000次修改 AOF持久化除了RDB外,Redis还提供了AOF。与RDB通过保存数据库快照不同,AOF是通过保存命令来记录数据库数据的。默认情况下,Redis是没有开启AOF的,可以通过配置redis.conf文件来开启AOF持久化,关于AOF的配置如下:
# appendonly参数开启AOF持久化 appendonly no # AOF持久化的文件名,默认是appendonly.aof appendfilename "appendonly.aof" # AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的 dir ./ # 同步策略 # appendfsync always appendfsync everysec # appendfsync no # aof重写期间是否同步 no-appendfsync-on-rewrite no # 重写触发配置 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # 加载aof出错如何处理 aof-load-truncated yes # 文件重写策略 aof-rewrite-incremental-fsync yes AOF持久化实现AOF需要记录Redis的每个命令,步骤分为:命令追加(append)、文件写入(write)和文件同步(sync)。
命令追加当AOF持久化功能处于打开状态时,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器状态的 aof_buf 缓冲区的末尾。
文件写入和同步关于何时将 aof_buf 缓冲区的内容写入AOF文件中,Redis提供了三种策略:
appendfsync always:将aof_buf缓冲区中的所有内容写入并同步到AOF文件。
appendfsync everysec:将aof_buf缓冲区中的所有内容写入到AOF文件,如果上次同步AOF文件的时间距离现在超过1秒,那么两次对AOF文件进行同步,并且这个同步操作是由一个线程专门负责执行的。
appendfsync no:将aof_buf缓冲区中的所有内容写入到AOF文件,但并不对AOF文件进行同步,何时同步由操作系统来决定。
关于AOF的同步策略是涉及到操作系统的 write 函数和 fsync 函数的,在《Redis设计与实现》中是这样说明的:
为了提高文件写入效率,在现代操作系统中,当用户调用write函数,将一些数据写入文件时,操作系统通常会将数据暂存到一个内存缓冲区里,当缓冲区的空间被填满或超过了指定时限后,才真正将缓冲区的数据写入到磁盘里。
这样的操作虽然提高了效率,但也为数据写入带来了安全问题:如果计算机停机,内存缓冲区中的数据会丢失。为此,系统提供了fsync、fdatasync同步函数,可以强制操作系统立刻将缓冲区中的数据写入到硬盘里,从而确保写入数据的安全性。