Redis持久化

作为一个优秀的分布式基础服务,Reids的设计很值得我们学习。本文就介绍一下Redis的持久化机制

什么是持久化

Redis的性能出色,其中一个很重要的原因是其基于内存的特性。但如果作为一个存储中间件,基于内存是万万不行的,因为万一服务器出现故障,重启以后就啥都没有了。

所以,Redis需要另外一套持久化机制将内存中的数据持久化到硬盘上,这样即使发生了不可预知的宕机事件,我们只需要将硬盘上的数据恢复到内存即可。

RDB 持久化

Redis的持久化机制一共有两种,我们先介绍第一种,就是RDB文件持久化。

RDB文件持久化就是将当前Redis数据库的状态保存成一份RDB文件,类似于一个快照的形式。然后Redis重启时直接载入RDB文件即可恢复宕机前的状态。(当然,数据可能存在不一致,因为可能会存在生成RDB尚未完成时宕机)

RDB保存命令

RDB的保存命令一共有两个,一个是SAVE、一个是BGSAVE。

两者的区别主要是前者会阻塞Redis进程,后者是fork出一个子进程进行复制。

所以,如果使用SAVE命令执行复制,客户端所有请求都会被阻塞,只有在复制完成时命令才可以被执行。而BGSAVE执行时只会影响SAVE、GBSAVE、BGREWRITEAOF三个命令,其余客户端命令则都不受影响。

RDB文件结构

一个RDB文件主要有5个部分组成:

AOF持久化

与RDB文件快照形式不同的是,Redis还提供了一个基于增量更新的AOF持久化模式。

假设客户端执行了 SET aaa bbbSET bbb cccSET ccc ddd 三个命令,RDB的的存储方式是将这三个键值对存放在RDB文件中,而AOF则是将这三条命令存放在AOF文件中。

AOF持久化实现

AOF命令重写

我们来看一个很简单的例子:

SET aaa bbb

SET aaa ccc

SET aaa ddd

按照我们上面的介绍,在AOF文件里,将会存在3个命令,但事实上这3个命令操作的是同一个键,我们只需要保存最终效果即可,并不需要完整保存这3个命令。

所以Redis对于AOF机制加了一个重写的功能,通过该功能,Redis服务器可以创建一个新的AOF文件,过滤掉那些冗余的命令。

但实际上Redis的实现并不是通过分析AOF文件去重再重新生成,而是直接分析数据库当前状态,例如当前数据库的键值对是aaa ddd,那就不需要再添加SET aaa bbbSET aaa ccc这两个命令了。

总结

RDB类似于系统快照,可以一个小时备份一次,出现宕机实践恢复比较快,而且备份过程是fork子进程处理的,不会阻塞父进程。

但是既然是快照,就不可避免会丢失一部分数据。所以,如果你的应用对丢失数据极为敏感,那么RDB不适合你。

AOF的好处是你可以根据不同的系统状态设置不一样的同步策略,尽可能的避免数据丢失。

但AOF的速度会慢于RDB,而且文件会比RDB大很多,重新加载的时间也更长。而且Redis的AOF有一些Bug,可能会导致AOF重新加载时无法恢复成保存时的原样。

Table of Contents