文章目录概括
1、RDB持久化的概念
该功能是将Redis内存中的数据库状态保存到磁盘中,避免数据意外丢失。
2、RDB文件
它是经过压缩的二进制文件,有多个部分组成,用于保存和还原Redis服务器所有数据库中的所有键值对。
RDB文件结构
REDIS:是一个常量值,占用了五个字节,通过这五个字符,程序可以在载入文件时,快速检查所载入的文件是否RDB文件。
db_version:占用4字节,它的值是一个字符串表示的整数,这个整数记录了RDB文件的版本号,例如:0006表示RDB文件第六版
databases:包含着零个或任意多个数据库,以及各个数据库中的键值对数据
EOF:常量的长度为1字节,这个常量标志着RDB文件正文内容的结束,当读入程序遇到这个值的时候,它知道所有数据库的所有键值对都已经加载完毕了。
check_sum是一个8字节长的无符号整数,保存着一个校验和,这个校验和是程序通过对REDIS、db_version、databases、EOF四个部分的内容进行计算得出的。
而指定的databases还需要根据不同的键值对类型来进行不同的设置,这里说一下整体的格式:
SELECTDB:是一个常量,表示下一个数值是对应的数据库号码
key_value_pairs:是键值对,这个键值对,会根据是否过期以及不同的类型,进行一个不同的存储,文件格式为:
此处的TYPE记录了value的类型,长度为1字节会根据不同的TYPE存储不同的键值对,Type类型为:
- REDIS_RDB_TYPE_STRING
- REDIS_RDB_TYPE_LIST
- REDIS_RDB_TYPE_SET
- REDIS_RDB_TYPE_ZSET
- REDIS_RDB_TYPE_HASH
- REDIS_RDB_TYPE_LIST_ZIPLIST
- REDIS_RDB_TYPE_SET_INTSET
- REDIS_RDB_TYPE_ZSET_ZIPLIST
- REDIS_RDB_TYPE_HASH_ZIPLIST
当中的key总是一个字符串对象,编码方式和REDIS_RDB_TYPE_STRING类型的value一样。
对于value的说明,在后面第五点会说到。
3、SAVE命令和BGSAVE命令
这两个命令时用于生成RDB文件,但是二者具有不同的执行方式
- SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完毕,在服务器创建RDB文件也就是服务器阻塞期间,Redis服务器不能进行其他操作。
- BGSAVE命令会派生出一个子进程,使用这个子进程来创建RDB文件,服务器进程在此期间,还能执行其他操作,能继续处理命令请求。需要注意的一点,就是在子进程创建完RDB文件之后,会向父进程发送信号(这是Redis服务器之间的通信方式,后面文章会谈到), 而父进程会轮询等待子进程的信号。
这两个命令执行时,也就是创建和加载RDB文件时,调用底层函数为:
而在执行SAVE、BGSAVE、BGREWRITEAOF命令时,需要注意以下几点:
- 在BGSAVE命令执行期间,客户端发送的SAVE命令会被服务器拒绝,因为服务器禁止这两个命令同时执行,为了防止在父进程和子进程同时执行两个rdbSave调用,防止产生竞争条件。
- 在BGSAVE命令执行时,客户端发送的BGSAVE命令会被服务器拒绝,因为两个BGSAVE命令也会产生竞争条件。
- BGREWRITEAOF和BGSAVE命令也不能同时执行:
- 如果BGSAVE正在执行,那么客户端发送的BGREWRITEAOF会被延迟到BGSAVE命令执行完毕之后执行。
- 如果BGREWRITEAOF正在执行,那么客户端发送的BGSAVE会被服务器拒绝。
4、服务器状态中会保存所有用save选项设置的保存条件,当任意一个保存条件被满足时,服务器会自动执行BGSAVE命令
谈到保存条件的设置,我们根据redis.conf文件中的配置可以看出来
其中可以看出,白色部分就是我们设置的保存条件,它的意思是:
- 服务器在900秒之内,对数据库进行了至少1次修改。
- 服务器在300秒之内,对数据库进行了至少10次修改。
- 服务器在60秒之内,对数据库进行了至少10000次修改。
在服务器启动时,用户可以根据指定配置文件中的上述的保存条件或者传入参数的形式来设置保存条件,而服务器会将其保存到服务器状态redisServer结构中的saveparams属性中,而saveparams属性是一个数组,数组中的每个元素都是一个saveparam结构,每个saveparam结构都保存了一个save选项设置的保存条件。
5、对于不同类型的键值对,RDB文件会使用不同的方式来保存它们