Redis持久化

持久化就是讲内存中的数据库状态保存到磁盘上。

 

数据库状态:我们将数据库服务器中的非空数据库以及他们的键值对通常称为数据库状态。

 

Redis是一个key-value数据库服务器,一般默认是有16个数据库,可以使用SELECT <index>命令进行切换(0-15)

 

Redis的两种持久化方式:一种是RDB持久化,一种是AOF持久化,这两种持久化方式都可以讲内存中的数据库状态保存到磁盘上,但是原理非常不同。

 

RDB持久化默认生成的文件名为dump.rdb,这个可以通过配置文件配置,RDB文件是一个经过压缩的二进制文件,接下来介绍一些rdb文件结构,RDB文件包含五个部分,分别是{Redis|db_version|databases|EOF|check_sum}开头的Redis表示这是一个RDB文件,服务器可以通过这个快速检查载入的文件是否是rdb文件,db_version是一个整数,代表RDB文件的版本,databases部分包含0个或者是任意多个数据库,以及数据库中的键值对数据,如果数据库状态是空,那么这部分也是空的,这部分的结构如下{SELECTDB|db_number|key_values_pairs}其中SELECTDB是一个常量,长度是一字节,当服务器遇到这个的时候,知道接下来要读入的将是一个数据库号码,db_number中保存的是一个数据库号码(0-15)这两部分结合就可以切换到相应的数据库,然后读取键值对,键值对的部分的结构由两种,一种是带过期值的,一种是不带过期值的,如果是带过期值的,那么结构是【EXPIRETIME_MS|ms|TYPE|key|value】第一个常量和SELECTDB一样,第二部分是毫秒为单位的unix时间戳,就是键值对的过期时间,然后是TYPE记录了value的类型,是String,list,set,zset,hash,等。不带过期值的键值对部分的结构没有前两部分,只是【TYPE|key|value】

 

RDB持久化可以通过两个命令进行手动执行,也可以配置好让服务器自动执行,手动执行可以使用Redis命令【SAVE】或【BGSAVE】,这两个命令有一些差别,需要说明一下,save命令会阻塞服务器进程,也就说,当save命令执行的时候服务器不能够处理任何命令请求,直到save命令执行完毕,RDB文件创建完毕,bgsave命令不会阻塞服务器,而是通过派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程继续处理命令请求,这里需要说明一下,bgsave处理期间,服务器虽然能够继续处理命令请求,但是save,bgsave,bgrewriteaof这三个命令的处理方式会和平时有所不同,在bgsave期间,save命令会被服务器拒绝,服务器禁止save和bgsave同时执行,避免父进程和子进程同时执行两个rdb,save(创建rdb文件的实际工作实际上是由rdbSave函数完成,save和bgsave都会调用这个函数,只是调用的方式不同),bgsave命令在bgsave期间也会被拒绝,理由和拒绝save理由一样,两个bgsave也会产生竞争,bgrewriteaof命令会被延迟到bgsave执行完毕之后执行。

 

Redis没有专门的RDB文件载入命令,只要Redis服务器开启,就会检测RDB文件是否存在,就会自动载入RDB文件,这里需要说明一点,如果服务器开启了AOF持久化功能,服务器会优先使用AOF文件来还原数据库状态,只有在AOF持久化功能关闭的时候,才会使用RDB文件来还原数据库状态。

 

RDB自动保存,RDB可以通过手动执行,SAVE命令和BGSAVE命令,也可以通过配置让服务器自动执行

 

Redis.conf中可以配置,默认配置如下:

 

save 900 1

save 300 10

save 60 10000

 

以上表示的意思是,

  • 900秒之内对服务进行了至少一次修改
  • 300秒之内服务器进行了至少10次修改
  • 60秒之内对服务器进行了至少10000次修改。

满足其中的任意一个bgsave命令就会自动执行。

服务器中有个dirty计数器和一个lastsave时间戳

当服务器执行一个数据库修改命令之后,dirty计数器就会进行更新,命令修改了多少次数据库,dirty就会增加多少,【set msg  hello】修改了一个,那么dirty就加一,如果【mset msg word name nihao age 20】那么dirty就增加三

Lastsave属性记录上次服务器执行保存操作的时间,是一个unix时间戳,通过这两个,可以很简单的计算距离上次保存已经多少时间了,以及修改了多少次数据库,一旦满足以上三个条件,那么久自动调用bgsave命令,服务器才会去执行,然后给客户端返回结果)

Redis本身自带了一个RDB文件检查工具redis-check-dump,可以使用这个工具对rdb文件时候完成进行检查。