10.1 RDB文件的创建与载入
redis是内存数据库,但为了防止服务重启,数据丢失,RDB持久化可以将redis在内存中的数据库状态保存到磁盘里面。
RDB持久化可以手动执行,也可以根据服务器配置选项定期执行,该功能可以将某个时间点上的数据库状态保存到一个RDB文件中。
有两个redis命令可以用于生成RDB文件,SAVE和BGSAVE。
SAVE命令活阻塞服务器进程,知道RDB文件创建完毕为止,在服务器阻塞i期间,服务器不能处理任何请求。
BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令请求。
RDB的载入工作是在服务器启动的时候自动执行的,没有专门的命令
值得一提的是:因为aof持久化比RDB文件的更新频率高所以:
1)如果服务器开启了AOF持久功能,服务器优先会使用AOF文件来还原数据库状态。
2)只有aof持久化关闭的情况下,服务器才会使用RDB文件来还原数据库状态。
在BGSABVE命令执行期间,客户端发送SAVE命令会被服务器拒绝的,因为同时执行会产生子进程和父进程竞争。如果客户端发送BGSAVE命令也会被服务器拒绝,也是因为他们会产生竞争的。
RDB文件载入时,会一直处于阻塞状态,直到载入完成。
10.2 自动间隔性保存
redis定期保存RDB文件,需要设置saveParams属性:
saveParam有两个属性 seconds //秒数
changes//修改数
除了saveParams参数之外,服务器还维持着一个dirty计数器,以及一个lastsave属性
dirty计算器记录了距离上一次SAVE命令或者BGSAVE之后,服务器对数据库进行了多少次修改。
lastsave属性记录了服务器上一次成功执行SAVE命令或者BGSAVE命令的时间。
redis的服务器周期函数 serverCOre默认100ms就会执行一次,该函数会检查save选项所设置的保存条件是否已经满足,如果满足就会执行BGSAVE命令。
AOF持久化
与RDB持久化通过保存数据库键值对来记录数据库状态不通,AOF是通过保存redis服务器所执行的写命令来记录数据库状态的。
AOF持久化功能的实现可以分为命令追加,文件写入,文件同步三个步骤。
1)命令追加:当AOF开启的时,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器状态的aof-buff缓冲区的末尾
2)aof文件的写入和同步
在服务器每次结束一个时间循环之前,都会调用flushappendonlyfile函数,考虑是否需要将aof-buff缓冲区的内容写入和保存到aof文件中
aof文件的载入和数据还原
载入比较简单,redis服务器创建一个不联网的伪客户端,然后读取aof的写命令就可以了。
AOF重写
aof文件记录redis的写命令,随着时间的运行,aof文件会越来越大,对磁盘以及后期载入都会产生严重后果。
为了解决aof文件写命令的冗余,redis提供了aof文件重写的功能。
虽然redis将新生成的AOF文件命名为“AOF重写文件”,但实际上,AOF文件重写并不需要对现有文件进行任何读取,分离或者写入操作,这个功能是通过读取服务器当前的数据库状态来实现的。
AOF后台重写
aof重写程序aof_rewirte函数可以完成创建一个新的aof文件,但是因为这个函数会进行大量的写入操作,所以调用这个函数的线程会被大量阻塞,所以在重写aof期间,服务期将无法处理客户端发来的命令请求。
redis决定将AOF重写程序放到子进程里执行。这样不回阻塞主线程处理客户端的命令。
但是这样会有一个问题需要解决,因为子进程在进行AOF重写期间,服务器还需要处理客户端的请求,而新的命令可以会对现有的数据状态,从而使得重写的AOF文件和数据库状态不一致。
为了解决这种数据不一致的问题,redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当redis完成一个写命令,它会同时将这个写命令发送给AOF缓冲区和aof重写缓存区。
以上部分 只是总结,如有不明白可以查看redis设计与实现第10,11章