Redis的持久化RDB和AOF原理

Redis持久化
redis所有数据全部存在内存中,如果突然宕机了,数据就会全部丢失,那么数据必须要持久化到磁盘中。那redis提供了几种持久化机制呢?
redis根据实际业务情况分为二种持久化机制。一种是rdb快照,另外一种是AOF文件
RDB快照
rdb快照是一种全量数据备份机制。每次备份数据都是全部内存的数据持久化到磁盘上。大家知道redis是单进程,单线程的程序。这个线程既要负责多个客户端socket的并发读写操作,也要负责内存数据落地磁盘的多写操作。那redis怎么保证快的呢?
这里先不纠结redis为什么快,redis快是因为都是内存操作以及epoll多路复用机制。向上面说的redis单进程单线程可以通过数据内存操作以及epoll多路复用保证redis的快,那redis怎么保证即对外提供读写数据,也可以保证数据入磁盘呢?毕竟I/O操作很耗时的,且I/O操作也不能多路复用,文件I/O会严重影响服务器性能。
redis是借用操作系统的多进程COW(copy-on-write)机制来实现快照的。
COW
cow机制是写时复制机制。redis是怎么使用这个机制的?
redis会操作系统调用函数fork出子进程。这里要了解fork子进程的机制。fork出的子进程和父进程是共享内存数据的。也就是一开始redis需要快照的时候,会fork子进程。子进程和主进程共享内数据,如内存的一块数据的指针引用,主进程存一份,子进程存一份。子进程遍历数据读取,序列化写入磁盘中。这时候主进程持续客户度提供服务,持续对内存数据修改,是通过COW机制进行的。这个机制是父进程对内存一页数据修改时候,是将这个内存页数据复制出来,然后对这个复制内存页数据进行修改。子进程还是fork那一瞬间的数据。,这个就是快照数据。
而且通过cow机制,父子进程占用内存不会是原来数据的2倍。除非所有的页都被主进程修改了。
RDB的缺点就很明显了,redis不能一直fork子进程来持久化。一般都是根据配置文件的周期来持久化的,如果在这个周期之外,服务器宕机了,从上个持久化后到宕机的时刻的内存数据就会丢失。
AOF原理
AOF即append of file,文件追加数据。也就是AOF存的是客户端操作的一系列的指令数据,这个指令数据是顺序持久化到文件中。这样的好处就是当系统宕机后,redis可以根据AOF文件里的指令集数据重新执行一遍,就可以恢复redis的数据了。但是一台redis实例长时间后,AOF的文件会非常大,且可能redis实际内存数据不大。如果这时候对redis进行重启,恢复AOF数据的时候会非常耗时。redis长时间不能对外提供服务了。这是AOF重写就被redis作者提出来
AOF重写
redis提供AOF重新命令:BGREWRITEAOF。这个指令会丢AOF日志进行瘦身。和RDB的快照原理一样,先fork子进程出来,子进程对内存数据遍历,转为一系列的REDIS的指令,序列化到新的AOF文件中,且将在序列化过程中产生的增量AOF日志追加到新的AOF文件中。也就是消除重复的指令,抵消无效的指令。
可这样不便能保证数据不丢失啊,那不是和快照一样吗?因为AOF日志重写,只是将内存数据放入到内核为该文件描述符分配的内存缓冲中,然后内核会异步将数据刷回磁盘。内存缓冲区的数据会丢失。
REDIS会调用系统的fsync(),将内存的数据强制刷到磁盘中。但是这个操作I/O很耗时。redis提供了3中方式,一般默认选择每秒执行一次fsync

参考
<<REDIS核心原理与应用实践>>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值