分布式|redis持久化,面试必问!!!

与天地兮比寿,与日月兮齐光。这篇文章主要讲述分布式|redis持久化,面试必问!!!相关的知识,希望能为你提供帮助。
四、redis持久化 为什么需要持久化?

【分布式|redis持久化,面试必问!!!】
redis的数据都是存放到内存中的,如果突然宕机,数据就会全部丢失,因此必须有一种机制来保证redis在内存中的数据不会丢失,这种机制就叫redis持久化机制。

持久化的方式

redis持久化分为两种,第一种是快照,第二种是AOF日志,快照是一次全量备份,AOF是连续的增量备份

快照的原理

我们知道Redis是单线程程序,这个线程要同时负责多个客户端套接字的并发读写擦欧总和内存数据结构的逻辑读写。
在服务线上请求的同时,redis还需要进行内存快照,进行持久化,需要进行文件IO操作,文件IO操作不能使用多路复用API的。
那么单线程的redis如何既能保证处理客户端的请求又能一边持久化呢?在持久化的同时,产生的新数据怎么办?
redis使用cow(copy on write)机制来实现。

fork(多进程)

redis在持久化的时候会调用glibc的函数fork产生一个子进程,快照持久化交给子进程来处理,不影响父进程继续处理客户端的请求,子进程持久化的时候,不会修改现有内存的数据结构,他只会对数据进行遍历读取,父进程会不断对数据进行修改。
在持久化的那一刻,子进程和父进行共享的数据将会使用Cow机制进行数据段页面分离,所以父进程对数据的修改不会影响持久化的数据,父进程修改数据会复制一份当前的页面进行修改,也就是在产生子进程的那一刻,需要持久化的数据已经固定下来了。


AOF原理

AOF日志存储的是redis服务器的顺序指令序列,AOF日志只记录对内存进行修改的指令记录,如果需要对一个空的redis实例进行恢复,那就只需要重放这些指令就可以,来恢复当前的状态。
reids在收到客户端指令修改后,先进行参数校验、逻辑处理,如果没有问题,就立刻将为本存储到AOF日志中,redis在长期的运行过程中,AOF的日志会越来越长,如果实例宕机重启,重放整个AOF会非常慢,导致redis长时间无法对外提供服务,所以就需要对aof日志进行瘦身。

AOF重写

redis提供了bgrewriteaof指令用于对AOF日志进行瘦身,其原理就是开辟一个子进程对内存进行遍历,转换成一系列redis操作指令,序列化到一个新的aof日志中。序列化完成之后,会将这期间新增的指令追加到aof日志后面,最后就可以用新的日志文件代替旧的日志文件了

fsync

AOF是以文件的形式存在的,当程序对AOF日志进行操作时,是把数据写到内存缓存中,之后由内核异步将数据刷到磁盘中,如果这时候机器宕机,AOF的内容还没来得及刷到磁盘中,这段时间产生的数据就会全部丢失,这该怎么办呢?
Linux的glibc提供了fsync函数可以强制将内存缓存中的内容刷到磁盘,不再需要等待内核异步去刷新。fsync是一个磁盘IO操作,所以会很慢,如果每执行一条redis指令,就调用下fsync函数,那就会导致redis不再那么高性能了。
所以在生产环境下,reids是每隔1秒就执行一次fsync,而且这个是可以配置的。

redis4.0混合持久化

重启redis时,我们很少使用rdb来恢复内存状态,因为这样会丢失大量的数据,我们通常会使用AOF进行重放指令操作,这将是一个漫长的过程,需要花费很长的时间。
redis4.0引入了一个新的持久化选项——混合持久化,先读取快照进行恢复,然后读取增量的AOF日志,这里的AOF是继上一次产生快照后,产生的增量日志,不再是以前的全量日志。




    推荐阅读