一、Redis存储在内存中,如果服务器断电或者重启,内存中的数据会被清理,所以需要对Redis持久化操作,保证数据库的完整性;

二、Redis持久化的方式:快照、AOF日志;

三、快照与AOF各自特点:

1、快照是一次全量备份,AOF 日志是连续的增量备份

2、快照是内存数据的二进制序列化形式,在存储上非常紧凑,而 AOF 日志记录的是内存数据修改的指令记录文本

3、AOF 日志在长期的运行过程中会变的无比庞大,数据库重启时需要加载 AOF 日志进行指令重放,这个时间就会无比漫长,定期需要对AOF重写,使其瘦身

四、快照工作原理:

1、Redis 使用操作系统的多进程 COW(Copy On Write) 机制来实现快照持久化

2、fork(多线程)原理:

Redis 在持久化时会调用 glibc 的函数fork产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。子进程刚刚产生时,它和父进程共享内存里面的代码段和数据段。这是 Linux 操作系统的机制,为了节约内存资源。

子进程做持久化,不会修改内存数据结构,只是对数据遍历读取、序列化、写磁盘;父进程接受客户端请求,对内存数据结构不断修改。这个时候就会使用操作系统的 COW 机制来进行数据段页面的分离。数据段是由很多操作系统的页面组合而成,当父进程对其中一个页面的数据进行修改时,会将被共享的页面复制一份分离出来,然后对这个复制的页面进行修改。这时子进程相应的页面是没有变化的,还是进程产生时那一瞬间的数据就凝固了,再也不会改变,这也是被称为快照的原因,接下来子线程可以遍历数据,序列化到磁盘

五、AOF日志工作原理:

1、AOF 日志存储的是 Redis 服务器的顺序指令序列,AOF 日志只记录对内存进行修改的指令记录。

2、Redis 会在收到客户端修改指令后,进行参数校验进行逻辑处理后,如果没问题,就立即将该指令文本存储到 AOF 日志中,也就是先执行指令才将日志存盘

3、leveldb、hbase等存储引擎,它们都是先存储日志再做逻辑处理。

4、Redis在长期运行的过程中,AOF日志会越来越长,如果宕机,重放整个日志会很耗时,所以要进行AOF重写即瘦身

5、Redis 提供了 bgrewriteaof 指令对 AOF 日志进行瘦身。

6、瘦身原理:当AOF文件达到配置文件配置的大小时,开辟一个子进程对内存进行遍历转换成一系列 Redis 的操作指令,序列化到一个新的 AOF 日志文件中。序列化完毕后再将操作期间发生的增量 AOF 日志追加到这个新的 AOF 日志文件中,追加完毕后就立即替代旧的 AOF 日志文件了,瘦身工作就完成了

7、AOF 日志是以文件的形式存在的,当程序对 AOF 日志文件进行写操作时,实际上是将内容写到了内核为文件描述符分配的一个内存缓存中,然后内核会异步将脏数据刷回到磁盘的。

8、Linux 的glibc提供了fsync(int fd)函数可以将指定文件的内容强制从内核缓存刷到磁盘

9、文件 IO 操作是不能使用多路复用 API的的原因:常规的文件io操作(读写)是不会阻塞的,不管读多少字节,read一定会在有限的时间内返回。从终端设备或网络读则不一定。同样,写常规文件是不会阻塞的,而向终端设备或网络写则不一定