Redis持久化-RDB

245 阅读3分钟

简介

Redis是一个键值对数据库服务器,它将自己的数据全部保存在内存里面,那么一旦服务器退出,Redis里的数据就全部丢失了.为了解决这个问题,Redis提供了RDB持久化功能,这个功能可以将内存里的数据保存到磁盘上,避免因为数据库退出,造成数据的意外丢失.RDB持久化既可以手动执行,也可以根据服务器配置定期执行,该功能可以将某个时间点数据库上的数据全部保存到一个RDB文件中.只要Redis文件存在,Redis服务器就可以基于RDB文件来恢复数据到内存.

RDB文件的创建和载入

手动保存

Redis有两个命令可以生产RDB文件

  • SAVE
  • BGSAVE

RDB文件的载入没有专门的命令,服务启动的时候会自动检测RDB文件是否存在,存在的话就会自动载入RDB文件. AOF文件和RDB文件的载入顺序问题,如果服务器开启了AOF功能,那么服务器优先会使用AOF文件来恢复数据,只有AOF持久化功能处于关闭状态,Redis才会使用RDB文件来恢复数据.如图:

redis持久化载入顺序

  • SAVE命令执行时,Redis服务器会被阻塞,客户端发送的所有请求都会被拒绝,只有当SAVE命令执行完毕,客户端发送的请求才会被处理.
  • BGSAVE命令执行时,不像SAVE命令会阻塞服务器进程,它的执行不会阻塞服务器进程,BGSAVE会fork一个子进程来执行RDB文件的创建,此时服务器进程可以继续处理客户端发送来的请求.
  • SAVE,BGSAVE,BGREWRITEAOF这三个命令处于性能方面的考虑不能同时执行,因为这些命令执行时会有大量的磁盘写入操作.

自动间隔性保存

用户可以通过save选项设置多个保存条件,只要其中一个条件满足,服务器就会执行BGSAVE命令. 比如配置:

  • save 100 10 <服务器在100秒内,有10次修改>
  • save 300 50 <服务器在300秒内,有50次修改>
  • save 1000 100 <服务器在1000秒内,有100次修改>

那么只要满足上面三个条件之一,Redis服务器就会执行BGSAVE命令.

Redis内部是怎样实现的呢?

Redis内部维护了dirty和lastsave两个属性.

dirty属性的意思是,距离上一次成功执行SAVE或者BGSAVE之后,服务器进行了多少次修改操作(新增,修改,删除等操作).

lastsave属性记录了距离上一次成功执行SAVE或者BGSAVE的时间戳.

有了这两个属性还不行,程序是怎么触发的呢? Redis服务器默认每隔100毫秒就会执行一次 serverCron函数,其中一项任务就是检查save选项的保存条件是否已经满足触发条件.