5.redis持久化(RDB)

272 阅读5分钟

redis提供了两种持久化方式,RDB和AOF,本章主要介绍RDB方式的持久化,AOF方式的持久化参考:redis持久化(AOF)

RDB持久化介绍

RDB持久化(Redis DataBase)指在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。

持久化过程中,Redis会单独创建(fork)一个子进程来进行持久化,子进程会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的RDB文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。

注:fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。

RDB持久化配置

RDB持久化数据默认保存在一个名为dump.rdb的RDB文件中,该文件位于dir所配置的目录下,持久化相关配置文件信息位于redis.confSNAPSHOTTING模块下。redis更多配置信息参考:redis配置文件

#持久化save格式:save <seconds> <changes>,表示在seconds秒内有changes次修改(增删改),则触发数据持久化
#禁用RDB持久化策略
save ""
#在900内有1次修改,则触发数据持久化
save 900 1
#在300内有10次修改,则触发数据持久化
save 300 10
#在60内有10000次修改,则触发数据持久化
save 60 10000
#如果后台持久化发生错误,是否停止前台数据写操作,默认开启
#如果配置成no,表示你不在乎数据不一致或者有其他的手段发现和控制
stop-writes-on-bgsave-error yes
#是否开启使用LZF算法压缩RDB文件,默认开启,开启则会增加CPU开销,但会减小持久化文件大小
rdbcompression yes
#在存储RDB文件后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
rdbchecksum yes
#RDB文件的名称,默认:dump.rdb
dbfilename dump.rdb
#是否删除在没有持久性的实例中复制使用的RDB文件,此选项仅在同时具有AOF的实例中有效(此配置我也不是很熟悉,注释说明来源于官网)
rdb-del-sync-files no
#redis工作目录,默认为当前开启redis服务所在的目录
#RDB和AOF文件将再次目录生成,同时也是数据库恢复的目录
#注意,这里必须指定目录,而不是文件名
dir ./

注:除了满足配置文件save配置项条件redis自动持久化外,可通过执行save和bgsave命令手动持久化。save会阻塞当前操作,bgsave则在后台默默持久化,不会阻塞当前操作,可通过lastsave命令获取最后一次保存RDB文件的时间戳。redis-cli config set save ""动态停止redis持久化。

恢复数据

  1. 关闭AOF方式的持久化,因为当开启AOF持久化方式时,redis优先从AOF文件中恢复数据。 appendonly no
  2. 配置RDB文件名称,默认名称为dump.rdbdbfilename dump.rdb
  3. 配置从哪个目录下的RDB文件中恢复数据,默认位置为当前开启redis服务的路径。 dir ./
  4. 将有数据的dbfilename名称的RDB文件放到dir目录下,然后启动redis服务将自动从RDB文件中读取数据到内存。 注:执行shutdown、save、flushall、gbsave都会重新更新RDB文件,所以当没有停止redis服务时,将备份的RDB文件拷贝到相应的路径用于恢复数据后,再执行shutdown停止redis服务,此时生成新的RDB文件覆盖原有用于恢复数据的RDB文件,以致于导致数据恢复失败。

修复RDB文件

当RDB文件异常导致数据恢复失败时,可通过执行 redis-check-rdb <RDB文件名称> 命令来修复该文件。

优点

  1. 恢复数据的速度快,适用于大规模的数据恢复和完整性与一致性要求不高的数据。
  2. RDB文件是一个压缩的二进制数据文件,相对于AOF文件占用空间更小。

缺点

  1. 在一定间隔时间做一次持久化,所以如果redis意外宕掉,就会丢失最后一次持久化后的所有修改。
  2. Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性消耗内存资源。

总结

  • RDB是一个非常紧凑的文件。
  • RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能。
  • 与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些。
  • 数据丢失风险大,如果redis意外宕掉,就会丢失最后一次持久化后的所有修改。
  • RDB需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级不能相应客户端请求。