Redis 的设计与实现——(七)Redis持久化机制

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文件(这时阻塞了父进程)。

发布了47 篇原创文章 · 获赞 8 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/nanchengyu/article/details/89338031