持久化
1.RDB持久化
在Redis运行时,RDB程序将当前内存中的数据库快照保存到磁盘中,当Redis需要重启时,RDB程序会通过重载RDB文件来还原数据库.
保存(rdbSave)
- rdbSave负责将内存中的数据库数据以RDB格式保存到磁盘中,如果RDB文件已经存在将会替换已有的RDB文件.保存RDB文件期间会阻塞主进程,这段时间期间将不能处理新的客户端请求,直到保存完成为止.
- 为避免主进程阻塞,Redis提供了rdbSaveBackground函数.在新建的子进程中调用rdbSave,保存完成后会向主进程发送信号,同时主进程可以继续处理新的客户端请求.
读取(rdbLoad)
- 当Redis启动时,会根据配置的持久化模式,决定是否读取RDB文件,并将其中的对象保存到内存中.
- 载入RDB过程中,每载入1000个键就处理一次已经等待处理的客户端请求,但是目前仅处理订阅功能的命令(PUBLISH 、 SUBSCRIBE 、 PSUBSCRIBE 、 UNSUBSCRIBE 、 PUNSUBSCRIBE),其他一律返回错误信息.因为发布订阅功能是不写入数据库的,也就是不保存在Redis数据库的
创建一个快照
- 任何Redis客户端可以通过调用
BGSAVE命令创建一个快照.Redis将会创建一个子进程写入快照到硬盘,父进程继续响应其他Redis命令. - Redis客户端同样可以调用
SAVE命令创建一个快照,该命令将会导致Redis停止响应任何其他所有的命令,直到快照写入完成.这条命令并不常用,只有这几种情况可能会用,需要保存所有的数据到硬盘,并且允许等到快照完成,或者我们没有足够的内存执行BGSAVE. - 如果Redis配置了
save行,比如save 60 10000,表示自上次成功保存起,如果在60秒内已经发生10,000次写入,那么将会自动触发一个BGSAVE操作.当多行save被定义时,任何时间任意一行匹配到,都会触发一个BGSAVE. - 当Redis收到一个
SHUTDOWN命令,或收到一个标准的TERM信号时,Redis将会执行一个SAVE,阻断任何客户端执行进一步的命令,然后关闭. - 如果一个Redis服务器连接到另一个Redis服务器,并且发起
SYNC命令开启主从同步,主Redis将会启动一个BGSAVE操作如果其中一个尚未执行或上次任务未完成.
2.AOF持久化
以协议文本的方式,将所有对数据库进行的写入命令记录到AOF文件,达到记录数据库状态的目的.
保存
- 将客户端请求的命令转换为网络协议格式
- 将协议内容字符串追加到变量server.aof_buf中
- 当AOF系统达到设定的条件时,会调用aof_fsync(文件描述符号)将数据写入磁盘
其中第三步提到的设定条件,就是AOF性能的关键点.目前Redis支持三种保存条件机制:
- AOF_FSYNC_NO:不保存 此模式下,每执行一条客户端的命令,都会将协议字符串追加到server.aof_buf中,但不会执行写入磁盘. 写入只发生在: 1.Redis被正常关闭 2.Aof功能关闭 3.系统写缓存已满,或后台定时保存操作被执行 上面三种情况都会阻塞主进程,导致客户端请求失败
- AOF_FSYNC_EVERYSECS:每一秒保存一次 由后台子进程调用写入保存,不会阻塞主进程.如果发生宕机,那么最大丢失数据会在2s以内的数据.这也是默认的设置选项
- AOF_FSYNC_ALWAYS:每执行一个命令都保存一次 这种模式下,可以保证每一条客户端指令都被保存,保证数据不会丢失.但缺点就是性能大大下降,因为每一次操作都是独占性的,需要阻塞主进程.
读取 AOF保存的是数据协议格式的数据,所以只要将AOF中的数据转换为命令,模拟客户端重新执行一遍,就可以还原所有数据库状态. 读取的过程是:
- 创建模拟的客户端
- 读取AOF保存的文本,还原数据为原命令和原参数.然后使用模拟的客户端发出这个命令请求.
- 继续执行第二步,直到读取完AOF文件
3. Redis复制集启动过程
| Step | Master operations | Slave operations |
|---|---|---|
| 1 | (等待一个命令) | (重)连接到master; 发起SYNC命令 |
| 2 | 启动BGSAVE操作; 保存一个包含所有写命令的backlog,在BGSAVE之后发送 |
提供旧数据(如果有), 或返回错误的命令(视配置而定) |
| 3 | 完成BGSAVE; 开始发送快照到slave; 继续维持一个写命令的backlog |
丢弃所有旧数据(如果有); 开始读取接受到的dump |
| 4 | 结束发送快照到slave; 开始发送写命令的backlog到slave | 完成解析dump; 开始再次正常响应命令 |
| 5 | 完成发送backlog; 开始实时写指令,当它们发生时 | 完成执行backlog中的写命令; 继续执行命令,当它们发生时 |
在SYNC期间,slave将会刷掉所有自己的数据
警告: Redis不支持master-master复制集