RDB持久化
由于Redis是内存数据库,所以当数据库down的时候,所有数据都会丢失,为了防止数据的丢失,我们采用RDB将数据库状态保存为文件。首先生成RDB文件的命令有两个:SAVE 和 BGSAVE
SAVE命令会阻塞Redis服务器,直到RDB文件创建完成
BGSAVE则不阻塞服务器,创建一个子进程进行保存
RDB文件生成后,当Redis启动时,会自动载入这个文件,无需手动命令
注意:AOF比RDB的优先级要高,会默认先采用AOF恢复数据库,此外不允许重复的进行BGSAVE或者SAVE,载入RDB文件时也会一直阻塞
我们可以设置自动保存的条件来定时执行BGSAVE命令,保存在redisServer中的saveparam中,格式为,只要有一个条件被满足就会执行SAVE
此外,服务器保存Dirty属性用于记录上一次生成RDB文件以来有多少次的修改,lastSave记录上一次执行SAVE命令的时间
保存的RDB文件究竟长什么样呢?
其中每个database的内容如下:
当读入SELECTDB时相当于告诉Redis数据库选中哪个DB,将下面的数据回复到它里面。而具体的键值对的结构如下图:
AOF持久化
Append Only File~通过保存Redis执行的写命令实现持久化,以Redis的请求协议纯文本方式来记录。
命令追加:每执行一个命令,就将一个命令添加到server的AOF缓冲区中
文件写入与同步:
Redis的服务器其实是一个loop,不断接受客户端的请求(也就是一次event),一次请求过程中可能有写命令,会写入到AOF缓冲区,每次事件完成AOF缓冲区要不要写入到文件呢?有三种策略:always总是写入,everysec每秒(默认),no从不
如何从AOF文件恢复数据库呢?
创建一个伪客户端,逐条执行AOF命令
AOF文件重写
减小AOF文件的冗余,提供了BGREWRITEAOF命令,这个命令会读取数据库当前的状态并生成一条命令,为了避免阻塞主线程,也采用在子线程中进行的方式。这样就带来一个问题,主线程还在巴拉巴拉的执行,子线程去读取所有的数据库状态生成命令就会产生不一致的问题,如何解决呢?
提供一个AOF重写缓冲区
当子进程重写AOF完成时,会给父进程发信号,父进程收到后将AOF重写缓冲区的数据一次性写入AOF文件(这时阻塞了父进程)。