Redis持久化
0目的:
- 将Redis内存中数据库保存在磁盘里面,避免数据库的丢失。
- RDB通过保存数据库的键值对来记录。
- AOF通过保存服务器执行的写命令记录数据库状态。
1.RDB持久化
1.1 概念:
- RDB文件是经过RDB持久化所生成的经过压缩的二进制文件,通过该文件可以还原RDB文件生成时数据库的状态。
- RDB文件被保存在磁盘中。
1.2 RDB文件的创建与载入
1.2.1 RDB文件的生成
1.SAVE命令
- 阻塞Reids服务器的运行,直至RDB文件的生成。
- 用户可以设置多个
SAVE
命令,让服务器每隔一段时间执行一次BGSAVE
命令。
2.BGSAVE命令
- 通过子进程创建RDB文件,父进程此时并不会被阻塞。
- 在此期间,客户端发送的
SAVE
命令会被服务器拒绝,避免父进程和子进程同时执行,产生竞争。
1.2.2 RDB文件的载入
- Redis服务器在检测到RDBB文件时,便会自动载入RDB文件。
- RDB文件载入过程中,服务器会一直处于阻塞,直至载入完成。
1.2.3 Tips
- 因为AOF文件的更新频率比RDB文件的更新频率高,所以在开启AOF持久化功能后,系统默认使用AOF文件来进行还原数据库的工作。
1.3 RDB文件的结构
AOF持久化
1.概念
- AOF请求文件以Redis请求协议格式保存。
2.AOF持久化的实现
2.1 文件追加
- 当执行一个命令完毕时,会以协议格式的形式将被执行的命令追加到服务器状态缓冲区的末尾。
2.2 文件写入及文件同步
1.Redis服务器就是一个事件循环,这个循环包括文件事件和时间事件
- 文件事件: 接收客户端的命令以及向客户端发送命令回复。
- 时间事件: 执行定时需要运行的函数。
2.将缓冲区的内容写入和保存到AOF文件中
- 服务器每一次结束循环事件前都会调用
flushAppendOnFile
函数考虑是否将aof_buf
缓冲区文件写入和保存到AOF
文件中。flushAppendOnlyFile
函数的行为由服务器配置的appendfsync
选项的值来决定。
2.1always:
将aof_buf
缓冲区中的所有内容写入并保存到AOF
文件中去。
2.2everysec:
**默认值,**每个一秒便对AOF
文件进行同步,**同步工作由专门的线程进行,**并不会阻塞主线程的运行。
2.3no:
将aof_buf
缓冲区的所有内容写入到AOF
文件中,**但是并不对AOF文件进行同步,**何时同步由操作系统决定。
2.4 写入和同步的区别:- 为了提高写入文件的效率,在现在操作系统中,当用户调用
weite
函数,将一些数据写入到文件中去时,操作系统会暂时将写入的数据暂时保存到一个内存缓冲区中,待缓冲区被填满或者超过了指定的事件后,才真正的将缓冲区的数据写入到磁盘中去。- 这种做法显然提高了操作系统写入文件的效率,但是也为写入数据带来了安全问题,可能致使缓冲区内的数据因断电等而发生丢失。
- 为此,系统提供了
fsync
和fdatasync
两个函数,他们可以强制的让操作系统立即将缓冲区的数据写入到硬盘中,从而确保数据的安全性。
3.AOF文件的载入与数据还原
- 读入并重新执行一遍AOF文件中的写命令即可恢复。
- Redis会创建一个没有网络连接的伪客户端来执行写命令。
2.1引文Redis命令只能在客户端执行,所以要创建伪客户端。
2.2执行的写命令直接来源于AOF文件,所以并不需要网络连接。- 从AOF文件中分析并读取一条写命令。
- 使用伪客户端执行读取出来的写命令。
- 重复执行
3
和4
命令,直至数据库的状态被完整的加载出来。
4.AOF文件重写
1.概念:
解决
AOF
文件体积膨胀的问题,防止文件过大。
Redis服务器创建一个新的AOF
文件来替换旧的AOF
,新的AOF文件中并不包含冗余的命令。
2.AOF文件重写的实现
2.1 并不需要对原有的AOF文件进行任何读取、分析、写入,而是基于当前服务器数据库的状态来实现的。
3.AOF的后台重写
3.1 因为Redis是单线程的,如果由服务器调用
aof_rewrite
函数,重写期间会致使服务器无法处理来自客户端的请求。
3.2 后台重写会致使AOF文件中的内容和数据库状态不一致的情况出现。
3.3 为了解决后台重写带来的数据库不一致状态,Redis服务器设置了AOF缓冲区,这个缓冲区在服务器创建子线程重写AOF文件时生成。3.3.1执行客户端发来的命令。
3.3.2将执行后的写命令追加到AOF缓冲区。
3.3.3将执行后的写命令追加到AOF重写缓冲区。