Skip to content

持久化

Redis 的持久化机制有两种,第一种是快照,第二种是 AOF 日志。快照是一次全量备份,AOF 日志是连续的增量备份。快照是内存数据的二进制序列化形式,在存储上非常紧凑,而 AOF 日志记录的是内存数据修改的指令记录文本, 系统在重启的时候先夹在快照然后在重复AOF日志记录

快照原理

在快照的时候会进行IO文件操作,由于redis使用的是单线程,所以在快照的时候会影响用户的业务操作,redis为了解决这个问题使用操作系统的多进程 COW(Copy On Write) 机制来实现快照持久化。Redis 在持久化时会调用 glibc 的函数 fork 产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。 这两个进程会共享数据,当父进程需要修改数据的时候,操作系统会把数据段页面分离,复制新的数据页面出来进行修改;而此时子进程的数据页面没有发生变化,子进程可以安心的遍历数据持久化到磁盘。

AOF原理

AOF 日志存储的是 Redis 服务器的顺序指令序列,AOF 日志只记录对内存进行修改的指令记录。

Redis 会在收到客户端修改指令后,先进行参数校验,如果没问题,就立即将该指令文本存储到 AOF 日志中,也就是先存到磁盘,然后再执行指令。这样即使遇到突发宕机,已经存储到 AOF 日志的指令进行重放一下就可以恢复到宕机前的状态。

AOF 日志是以文件的形式存在的,当程序对 AOF 日志文件进行写操作时,实际上是将内容写到了内核为文件描述符分配的一个内存缓存中,然后内核会异步将脏数据刷回到磁盘的。linux操作系统 提供了fsync(int fd)函数,可以指定文件的内容强制从内核缓存刷新到磁盘。只要redis进程实时条用fsync函数就可以保证AOF日志不会丢失。 但是fsync使用IO操作,每执行一次命令就调用fsync会严重影响性能,所以在生成环境的服务器中,redis通常是每隔1s执行一次fsync操作。

快照通过子进程的方式进行,需要遍历整个内存,大块写磁盘操作;AOF的fsync是耗时的IO炒作,会降低redis的性能,所以通常情况下,redis主节点不会进行持久化操作,持久化操作主要是在从节点进行。

混合持久化

redis 4.0提供了混合持久化,把快照的内容与AOF日志存放在一起,这里AOF不再是全量的日志,而是持久化开始到持久化结束这段时间发生的增量AOF日志,这部分的AOF日志通常比较少

redis在重启的时候先加载快照的内容,再重放AOF日志,重启的效率大幅提高。

原文链接: http://herman7z.site