单机数据库实现——RDB持久化
因为Redis是内存数据库,它将自己的数据库中的键值对存储在了内存里面,所以入股不想办法将存储在内存中的键值对保存到磁盘里面,那么一旦服务器进程退出,服务器中的数据库状态也会消失不见。为了解决这个问题,Redis提供了RDB持久化功能,这个功能可以将Redis在内存中的数据库状态保存到磁盘里面,避免数据意外丢失。
RDB文件的创建与载入
创建:
有两个命令可以用于生成RDB文件,一个实SAVE,另一个实BGSAVE。SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞一件,服务器不能处理任何命令请求。
载入:
和创建RDB文件不同,RDB文件的载入工具是在服务器启动时自动执行的,所以Redis并没有专门用于载入RDB文件的命令,只要Redis服务器在启动时检测到RDB文件存在,它就会自动载入RDB文件。
另外一点:
AOF文件更新的频率通常比RDB文件的更新频率高,所以:
- 如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据库状态。
- 只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据库状态。
一,SAVE命令执行时的服务器状态
当SAVE命令执行时,Redis服务器会被阻塞,所以当SAVE命令正在被执行的时候,客户端发送的所有请求都会被阻塞。
二,BGSAVE命令执行时的服务器状态
BGSAVE命令的保存工作由子进程执行的,所以在子进程创建RDB文件的过程中,Redis服务器仍然可以继续处理客户端的命令请求,但是在BGSAVE命令执行期间客户端发送的SAVE命令会被服务器拒绝。在执行BGSAVE命令期间,客户端发送的BGSAVE命令会被服务器拒绝,因为同事执行两个BGSAVE命令也会产生竞争条件。
最后,BGREWRITEAOF和BGSAVE两个命令也不能同时执行:
- 如果BGSAVE正在执行,那么BGREWRITEAOF命令会被延迟到BGSAVE执行完毕后执行。
- 如果BGREWRITEAOF正在执行,那么BGSAVE会被服务器拒绝。
三,RDB文件载入时的服务器状态
服务器在载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成为止。
自动间隔性保存
在满足任一条件就会进行RDB持久化的默认配置为:
- 服务器在900秒之内,对数据库进行了至少1次修改
- 服务器在300秒之内,对数据库进行了至少10次修改
- 服务器在60秒之内,对数据库进行了至少10000次修改
一,设置保存条件
执行指令
save | 900 | 1 |
---|---|---|
save | 300 | 10 |
save | 60 | 10000 |
那么服务器中保存条件将会和默认值一样,同理我们在设置保存条件时可以修改对应的数字即可。
二,dirty计数器和lastsave属性
除了saveparams数组之外,服务器状态还维持这一个dirty计数器,以及一个lastsave属性:
- dirty计数器记录距离上一次成功执行SAVE命令或者BGSAVE命令之后,服务器对键值对(服务器中的所有数据库)进行多少次修改(包括写入,删除,更新等操作)。
- lastsave属性是一个UNIX时间戳,记录了服务器上一次成功执行SAVE命令或者BGSAVE命令的时间
三,检查保存条件是否满足
Redis的服务器周期性操作函数serverCron默认每隔100毫秒就会执行一次,该函数用于对正在运行的服务器进行维护,它的其中一项工作就是检查save选项所设置的保存条件是否已经满足,如果满足就执行BGSAVE命令。
RDB文件结构
分析RDB文件
上面这两节详细参考Sripathi Krishnan编写的《RedisRDB文件格式》文档