Redis持久化机制详解
众所周知Redis的所有数据都放在内存里,如果突然宕机,数据就会全部消失,从而Redis提供了数据持久化来保证其可靠性。Redis持久化机制有两种,一是快照,二是AOF日志。
快照
快照是某个时间点的一次全量数据备份,是二进制文件,在存储上非常紧凑。快照又分为手动触发和自动触。
手动触发
Redis提供save和bgsave两个命令来手动触发快照备份。
- save命令,会阻塞当前服务器直到快照完成为止,如果数据量大就会造成长时间无法处理客户端请求。
- bgsave命令,Redis主进程会fork一个子进程来完成快照,完成后自定结束。Redis阻塞的时间就只有fork子进程的一瞬间,之后就能继续处理客户端请求。
自动触发
- 配置redis.conf触发规则,自动执行。
- 执行shutdown命令关闭服务器时,如果没有开启AOF持久化功能,那么会自动执行一次bgsave。
- 主从同步(slave和master建立同步机制) 。
快照执行过程
Redis使用操作系统的多进程 COW(Copy On Write)机制来实现快照持久化。
首先,Redis在持久化时会调用glibc的函数fork产生一个子进程,快照持久化就会完全交给子进程来处理,父进程继续处理客户端请求。
其次,子进程在持久化过程中不会修改现有的内存数据结构,只是对数据结构进行遍历读取,然后序列化写到磁盘中。
然后,使用操作系统的COW机制进行数据段页面的分离,当父进程要对其中一页数据进行修改时,会复制一份数据以供其修改,子进程对应页面的数据不会变化。
最后,子进程完成持久化后会发消息给主进程,通知持久化完成。
因为子进程持久化对应数据没有变化,自始至终对应的都是某一时刻的数据,从而被称为快照。
AOF日志
AOF日志AOF日志只记录对内存进行修改的顺序指令集。Redis收到客户端修改指令后,进行参数校验、逻辑处理后,就会将该指令存储到AOF日志中,即先执行指令后进行AOF日志存储。所以如果想要恢复内存数据结构,通过AOF日志顺序重放指令即可。
Redis在长期运行的过程中,AOF日志会越来越长,重放整个AOF日志会非常耗时,所以就需要时常对AOF日志进行瘦身。
开启方式
AOF默认是关闭的,可以通过redis.conf配置文件来开启。
## 此选项为aof功能的开关,默认为“no”,可以通过“yes”来开启aof功能
## 只有在“yes”下,aof重写/文件同步等特性才会生效
appendonly yes
## 指定aof文件名称
appendfilename appendonly.aof
AOF重写
AOF日志随着运行时间的增长其日志大小也会增加,可以使用bgrewriteaof命令来对AOF日志进行瘦身,其原理就是Redis会fork一个子进程来对内存进行遍历,并转换成一系列Redis操作指令,最后序列化到一个新的AOF日志中,再替换就AOF日志文件。
Redis 4.0混合持久化
使用快照方式恢复数据,由于快照时间粒度较大回放时会丢失大量数据;使用AOF日志方式恢复数据,日志性能相对快照来说要慢,启动需要花费很长的时间。
Redis 4.0为了解决这个问题,增加了混合持久化。所谓混合就是将快照文件的内容和AOF日志文件存在一起,这样一来AOF日志就不再是全量日志文件,而是自快照持久化开始到结束这段时间的AOF日志,这样一来就大大的减少了AOF日志文件。
在Redis重启的时候,可以先加载快照文件的内容,然后再重放AOF日志文件,这样一来重启效率会得到大幅的提升。