Redis持久化
Redis的数据全部在内存里,假如遇到宕机的情况,数据就会全部丢失,所以采用一种持久化的方式将数据写入到磁盘中。
Redis的持久化共有两种,第一种是快照的方式,第二种是AOF日志。
两者的区别是,快照是全量存储,AOF是连续的增量备份,快照是内存数据的二进制序列化形式,AOF是内存数据的修改逻辑指令文件
原理
Redis为单线程程序,这个线程需要负责客户端的数据查询等操作,如果在一个线程中,既要完成数据存取、又要完成io操作,会严重拖垮服务器的性能,如果变读写边持久化,可能会出现数据冲突,所以Redis的持久化采用了copy on write进行,主进程fork出来一个子进程进行数据的持久化。
cow
Copy on Write
原理:
1. 父进程fork出来的子进程与父进程共享内存空间,内存空间中的数据并不会马上复制给子进程。
2. fork()之后,kernel把父进程中所有的内存页的权限都设为read-only,然后子进程的地址空间指向父进程。当父子进程都只读内存时,相安无事。当其中某个进程写内存时,CPU硬件检测到内存页是read-only的,于是触发页异常中断,kernel就会把触发的异常的页复制一份,于是父子进程各自持有独立的一份。
AOF
AOF日志存储的是redis服务器的顺序指令序列,AOF日志只对内存进行修改的指令记录。
通过顺序执行AOF的方式,来对redis内存操作进行重现,从而达到数据恢复的目的。
AOF日志不遵循日志先行的规则,所以这一点上,Redis并不适合做DB去进行存储。
AOF写入策略分为三种,一:redis每隔1s调用系统的fsync操作进行写入,二:让操作系统判断何时,三:每次来一个指令就调用一次fsync,通常redis采用的是第一种,在效率与安全性上做了一个折中。
混合持久化
redis采用混合持久化,因为在RDB(快照)的时候,会存在子进程正在持久化的数据父进程刚好改了,会存在数据丢失的问题,所以在回复的时候,可以采用RDB的快速恢复+AOF的增量恢复。AOF只保留子持久化开始到持久化结束这个时间段的数据。