Redis持久化原理总结
1:快照原理
Redis使用操作系统的多进程COW(copy on write)机制来实现快照持久化,Redis在持久化时会调用glibc的函数fork产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。子进程刚刚产生的时,它和父进程共享内存里面的代码段和数据段。子进程做数据持久化,不会修改现有的内存数据结构,它只是对数据结构进行遍历读取,然后序列化写到磁盘中。但是父进程会继续处理客户端的读写请求,然后对内存数据结构进行不断的修改。这时子进程相应的页面是没有变化的,还是进程产生时的那一瞬间的数据。子进程因为数据没有变化,它能看到的内存里面的数据在进程产生的一瞬间就凝固了,再也不会改变,这也是Redis持久化叫“快照"的原因。接下来子进程就可以非常安心的遍历数据,进行序列化写磁盘了。
rdb的劣势:
①:fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
②:虽然Redis在fork的时候使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能
③:被备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改
rdb的优势:
①:适合大规模的数据恢复
②:对数据完整性和一致性要求不高更适合使用
③:节省磁盘空间
④:恢复速度快
2:AOF原理
AOF日志存储的是Redis服务器的顺序指令序列,AOF日志只记录对内存进行修改的指令记录。Redis在长期运行的过程中,AOF日志会越来越长,所以需要对AOF日志文件进行瘦身。Redis提供了bgrewriteaof指令用于对AOF日志进行瘦身,其原理就是开启一个子进程对内存进行遍历,转化成一系列的Redis的操作指令,
序列化到一个新的AOF日志文件中,序列化完毕后再将操作期间发生的增量AOF日志追加到这个新的AOF日志文件中,追加完毕后就立即代替旧的AOF日志文件了,瘦身工作也就完成了。AOF日志是以文件的形式存在的,当程序对AOF日志文件进行写操作时,实际上是将内容写到了内核为文件描述符分配的一个内存缓冲中,然后内核会异步将数据刷回到磁盘的。Linux的glibc提供了fsync(int fd)函数可以将指定文件的内容强制从内核缓存刷到磁盘。只要Redis进程实时调用fsync函数就可以保证Aof日志不会丢失。但是fsync是一个磁盘IO操作,他很慢。一般在生产环境Redis同程是每隔1S左右同步一次,当然是可以进行配置的。
以日志的形式来记录每个写操作(增量保存),讲Redis执行过的所有写指令
记录下来。
aof和rdb同时开启,系统默认取AOF的数据(数据不会存在丢失)
优势:
备份机制更稳健 丢失数据概率更低
可读的日志文本,通过操作AOF稳健,可以处理误操作
劣势:
比起RDB占用更多的磁盘空间
恢复备份速度更慢
每次读写都同步的话 有一定的性能压力
存在个别bug,造成恢复不能
总结:
快照是通过开启子进程的方式进行的,他是一个比较耗资源的操作。
①:遍历整个内存,大块写磁盘会加重系统负载。
②:AOF的fsync是一个耗时的IO操作,它会降低Redis性能,同时也会增加系统IO负担。
所以通常在生产环境中,Redis主节点是不进行数据初始化的,持久化操作主要在从节点进行。从节点是备份节点,没有来自客户端请求的压力,它的操作系统资源往往比较充沛。