RDB持久化
Redis是内存数据库,数据存储在内存中,为了解决持久化问题,Redis提供了RDB持久化功能。

因为RDB文件是存储在磁盘中的,所以即使Redis服务器退出了,甚至运行Redis服务器的计算机停机,但只要RDB文件仍然存在,Redis服务器就可以用它来还原数据库状态。
RDB文件的创建和载入
SAVE
SAVE命令会阻塞Redis服务器进程,知道RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求,所以客户端发送的所有命令请求都会被拒绝。
BGSAVE
BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令请求。
载入:
RDB文件是在服务器启动的时候自动执行的,只要Redis服务器在启动时检测到RDB文件存在他就会载入RDB文件。
RDB文件载入期间,服务器处于阻塞状态,直到载入工作完成为止。
注意:
1:如果服务器开启了AOF持久化功能,服务器会优先使用AOF文件来还原数据库状态。
2:只有AOF持久化处于关闭状态时,服务器才会使用RDB文件来还原数据库状态。
为什么AOF文件比RDB文件优先级高? 因为AOF的更新频率通常比RDB文件的更新频率高,数据恢复的一致性能更加得得到保证。
SAVE、BGSAVE、BGREWRITEAOF(AOF重写)
BGSAVE执行期间,SAVE会被服务器拒绝,服务器禁止SAVE和BGSAVE同事执行,避免父进程和子进程同时执行,防止产生竞态条件。
其次,BGSAVE执行期间,客户端发送的BGSAVE也会被服务器拒绝,因为同时执行两个BGSAVE也会产生竞态条件。
BGSAVE和BGREWIRTEAOF也不能同时执行。
1:如果BGSAVE在执行,那么客户端发送的BGREWRITEAOF会被延迟到BGSAVE执行完毕之后。
2:如果BGREWRITEAOF在执行,那么BGSAVE命令将会被拒绝。
因为BGREWRITEAOF和BGSAVE两个命令的实际工作都是由子进程执行,所以这两个命令在操作方面并没有什么冲突的地方,不能同事执行它们只是一个性能方面的考虑---并发两个子进程,并且这两个子进程都是同时执行大量的磁盘写入操作(IO性能问题)。
RDB校验:
1:RDB文件在载入的时候,会将载入数据所计算出的校验和与check_sum所记录的校验和进行对比,以此来检查RDB文件是否出错或者损坏的情况出现。
重点回顾:
1:RDB文件用于保存和还原Redis服务器所有数据库中的所有键值对数据。
2:SAVE会阻塞服务器进程。
3:BGSAVE不会阻塞服务器进程,由子进程执行,Redis服务器经常保持工作。
4:RDB是一个经过压缩的二进制文件。
5:对于不同类型的键值对,RDB文件会使用不同的方式来保存他们。
AOF持久化
Redis除了提供RDB持久化之外,还提供了AOF持久化。 RDB持久化是记录数据库所有的键值对,而AOF持久化是记录对Redis服务器所执行的写操作命令来记录数据库状态。

AOF持久化的实现:
分为:命令追加(append),文件写入,文件同步(sync)三个步骤
命令追加
执行的写命令会追加到服务器的aof_buf缓冲区的末尾。
注意:缓冲区和缓存是不一样的概念。
文件写入
文件的写入是写入到文件的内存中,而不是刷盘。因为操作系统会先将文件读取到内存,进行读和写操作,因为这样能提高写入和读取的效率。
文件同步
将AOF文件同步到磁盘。
AOF文件的载入与数据还原
因为AOF文件里包含了重建数据库状态所需的所有写命令,所以服务器只要读入并重新执行一遍AOF文件里面保存的写命令就可以还原服务器关闭之前的数据库状态。
步骤:
1:创建一个不带网络连接的伪客户端:因为Redis的命令只能在客户端上下文中执行,而载入AOF文件时所使用的命令直接来源于AOF文件而不是网络连接,所以服务器使用一个没有网络连接的伪客户端来执行AOF文件保存的写入命令。
2:从AOF文件中分析并读取一条写命令。
3:使用伪客户端执行读出的写命令。
4:重复2,3步骤,直到AOF文件中所有写命令都被处理完毕为止。

AOF重写
因为AOF记录的是所有被执行的写命令,随着服务器的运行,AOF文件中的内容会越来越多,文件的体积也会越来越大,体积过大的AOF文件很可能对Redis服务器、甚至整个宿主计算机造成影响,并且AOF体积越大,Redis还原所需要的时间就会越多。
AOF重写的实现
Redis将新生成的AOF文件替换旧AOF文件。 AOF文件重写并不需要对现有的AOF文件进行任何的读取、分析或者写入操作,这个功能是通过读取服务器当前的数据库状态来实现的。
父进程会在重写期间,开启AOF重写缓冲区,记录在子进程重写期间,Redis服务器的写命令,在子进程完成AOF重写之后,会把AOF重写缓冲区的记录写入到重写的AOF文件中。
然后把新的AOF文件进行改名,原子地覆盖现有的AOF文件,完成新旧两个AOF文件的替换。
因为Redis是使用单线程处理命令请求,AOF重写会导致线程长时间阻塞,所以AOF重写程序是放到子进程中执行的。
子进程执行目的是:
1:子进程进行AOF重写期间,服务器进程(父进程)可以继续处理命令请求。
2:子进程带有服务器进程的数据副本,使用子进程而不是线程,可以避免使用锁的情况下,保证数据的安全性。