Redis之持久化

Redis是基于内存的数据库,而内存是断电即失的,因此我们需要持久化功能。

而Redis的持久化有两种,一种是RDB,一种是AOF。RDB是基于数据的持久化,记录的是数据库中的数据。AOF是基于状态的持久化,记录的是修改数据库的操作。

需要注意的是如果服务器开启了AOF持久化,则会优先使用AOF持久化功能。

RDB

RDB文件的创建与载入

有两个命令可以生成RDB文件。savebgsave

  • sava命令会阻塞Redis服务器进程,直到RDB文件创建完毕,在服务器进程被阻塞期间,服务器不能处理任何命令请求
  • bgsave命令会派生出一个子进程负责创建RDB文件,服务器进程会继续处理命令请求

但是,及时使用bgsave派生出子进程创建RDB文件时,服务器进程也不能再次执行命令创建RDB文件,也就是说,同时只能存在一个进程创建RDB文件

服务器在载入RDB文件期间(Redis服务器开启时会自动载入),会一直处于阻塞状态,直到载入工作完成

自动间隔性保存

用户可以通过save选项设置多个保存条件,只要任意一个条件被满足,服务器就会执行bgsave命令

save 900 1
save 300 10
save 60 10000

那么只要满足以下三个条件之一,bgsave命令就会被执行

  • 服务器在900秒之内,对数据库进行了至少1次修改
  • 服务器在300秒之内,对数据库进行了至少10次修改
  • 服务器在60秒之内,对数据库进行了至少10000次修改

以上也是redis默认的save条件。

redis会在服务器中维护一个记录,记录了当前距离上一次save或者bgsave间隔多少时间和数据库进行了多少次修改。

redis服务器会周期性的检查(默认100毫秒)save条件是否满足,若满足则执行bgsave命令。

AOF

AOF持久化功能的实现可以分为命令追加,文件写入,文件同步三个步骤

命令追加

当AOF持久化功能开启后,服务器在执行完一个修改命令后,会把改名了追加到aof_buf缓冲区的末尾

AOF文件写入和同步

写入:写入到内存缓冲区
同步: 同步到磁盘中

服务器配置的appendfsync决定了AOF持久化的效率和安全性。他一共有三个值:always,everysec,no

  • 当appendfsync的值为always时,服务器在每个事件循环都要将aof_buf缓冲区的内容写入AOF文件,并且同步AOF文件,所以always效率比较慢但是安全性比较高

  • 当appendfsync的值为everysec时,服务器在每个事件循环都要将aof_buf缓冲区的内容写入AOF文件,但是每隔一秒会调用子线程对AOF文件进行同步,从效率上看 everysec比较快,并且就算出现故障宕机,也只丢失1秒的数据

  • 当appendfsync的值为no时,服务器在每个事件循环都要将aof_buf缓冲区的内容写入AOF文件,何时同步AOF文件由操作系统决定,no时写入速度最快,但是出现故障宕机时会丢失上次同步到现在的数据

redis中appendfsync的值默认为everysec

AOF文件载入与数据还原

Redis读取AOF文件时会传建一个不带网络连接的伪客户端,伪客户端会执行AOF文件中的命令

AOF重写

因为AOF持久化是保存被执行的写命令来记录数据库状态的,所以随着时间的流逝,AOF文件中的内容会越来越大,AOF文件的体积也越来越大,为了解决这个问题,redis提供了AOF文件重写功能,通过该功能可以创建一个新的AOF文件来代替原来的AOF文件。

重写AOF文件是根据当前数据库的状态来实现的,举个例子

SADD animals "CAT"
SADD animals "DOG"
SADD animals "FISH"
SADD animals "PANDA"
SADD animals "TIGER"

这5条指令可以写为1条指令

SADD animas "CAT" "DOG" "FISH" "PANDA" "TIGER"

AOF重写功能是由后台进程来实现的,也就是说在进行AOF文件重写的过程中不会阻塞服务器进程。但是服务器进程新的命令会使得当前数据库状态和重写后的AOF文件不一致的情况。redis采用AOF重写缓冲区来解决这个问题。

若开始AOF重写后,服务器进程接到写命令会在AOF缓冲区和AOF重写缓冲区同时追加该命令,当重写AOF文件完成后,服务器会阻塞等待AOF重写缓冲区的命令写入到新的AOF文件中。

posted @ 2021-10-18 20:10  刚刚好。  阅读(142)  评论(0编辑  收藏  举报