RDB持久化
创建与载入
SAVE命令会阻塞Redis服务器进程,知道RDB文件创建完毕为止,在服务器阻塞期间,服务器不能处理任何命令请求。
BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器继续处理请求。
如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据库的状态。只有AOF功能关闭,服务器才会使用RDB文件来还原数据库状态。
在执行命令BGSAVE期间客户端发来的BGSAVE或者SAVE命令都会被服务器拒绝,目的是为了防止产生资源征用问题。如果BGSAVE在执行期间发来BGREWRITEAOF命令会被延迟到BGSAVE执行之后执行。
如果BGSAVEWRITEAOF命令正在执行,那么客户端发送的BGSAVE命令会被服务器拒绝。
RDB文件载入时的服务器会一直处于阻塞状态,直到工作完成为止。
用户可以指定save参数,让redis服务器定期执行BGSAVE。
Eg: save 900 1 服务器在900秒内对数据库执行最少1次修改
save 300 1 服务器在300秒内对数据库执行最少10次修改
save 60 10000 服务器在60秒内对数据库执行最少10000次修改
dirty计数器和lastsave属性
dirty计数器记录距离上一次成功执行SAVE命令或者BGSAVE命令之后,服务器对数据库状态进行了所少次修改(写入、删除、更新)
lastsave:是一个时间戳,记录服务器上一次成功执行SAVE命令或者BGSAVE命令的时间。
Redis服务器会定期检查是否满足save命令。
文件结构
![](https://img.haomeiwen.com/i11774306/fc306305fd9a2aff.png)
- REDIS:用于快速检查是否是RDB文件。
- Db_version:RDB文件版本号。
- EOF:文件结束标志。
- Check_sum:校验和。
Database部分:
![](https://img.haomeiwen.com/i11774306/6fc593266cc48307.png)
一个RDB文件的databases部分可以保存任意多个非空数据库。
图中databases 0代表0号数据库中所有的键值对数据,databases 3代表3号数据库中所有的键值对数据。
完整的RDB文件:
![](https://img.haomeiwen.com/i11774306/73cd43d0ef4ecf22.png)
Key_value_pairs部分
![](https://img.haomeiwen.com/i11774306/05c7f67b1bc19178.png)
![](https://img.haomeiwen.com/i11774306/5ae0e8e97e6e9d5b.png)
ms:记录过期时间的时间戳
value的编码:
字符串对象
如果字符串的长度小于20,会被原样保存,超过20会被保存压缩后的字节。
列表对象
![](https://img.haomeiwen.com/i11774306/2b9fcb1bbd5b792f.png)
Item会保存元素的长度及元素的信息。
例如:列表中存:”hello” “world” “!”
![](https://img.haomeiwen.com/i11774306/bc81e472e1981593.png)
集合对象
![](https://img.haomeiwen.com/i11774306/7c828303105993b7.png)
![](https://img.haomeiwen.com/i11774306/6aebabd4e102f2f7.png)
哈希对象
![](https://img.haomeiwen.com/i11774306/0d3c74be0a6d3f3f.png)
有序集合对象
和hash对象基本一致
INTSET编码集合:先将整数转换为字符串进行持久化,RDB载入时会将字符串转换为整数。
ZIPLIST编码的列表
- 将压缩列表转换为一个字符串对象
- 将转换后的字符串对象保存到RDB文件中