Redis快速恢复数据:RDB快照

270 阅读2分钟

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

上一篇说了Redis避免数据丢失的方法,AOF日志详情

今天说一下Redis另外一种持久化方式:RDB快照。

RDB快照

RDB快照就是把数据在某一时刻的状态以文件的形式保存在磁盘中。

Redis利用写时复制技术COW(copy on write)实现快照持久化,在持久化时调用glibc的函数fork一个子进程。子进程负责快照持久化,主线程负责继续处理客户端请求。父子进程共享内存里面的数据。主线程处理客户端请求时,会把数据页复制一份出来进行修改,原有数据页不会动。子进程因为数据没有变化,在fork子进程的时候数据就已经凝固了,所以可以进行持久化。这既保证了快照的完整性,也允许主线程同时对数据进行修改,避免了对正常业务的影响。

有两个命令可以执行RDB快照。

  • save :save命令会阻塞服务器主进程,直到RDB文件创建完毕为止。在服务器阻塞期间,服务器不能处理其他任何命令。(基本已不会使用)

  • bgsave :首先会创建一个子进程,创建RDB文件,避免主线程的阻塞(默认配置)。

RDB快照会阻塞主线程吗?

RDB快照在执行持久化的过程中并不会阻塞主线程,但是在fork创建子进程的过程会阻塞主线程。执行快照的时刻,Redis存储的数据越多,阻塞的时间就越长。

因此也不能频繁的执行RDB快照,一方面是间隔太短导致上一个快照还没有执行完毕,磁盘压力很大;另一方面频繁执行快照,就会频繁fork子进程,导致不断阻塞Redis主线程。

AOF日志能够使Redis丢失的数据更少,为什么还要使用RDB快照呢?

AOF内存储的使每一条执行的命令,Redis宕机后,用来恢复数据会很慢。而RDB快照存储的是二进制数据,能够更快的恢复数据。并且RDB快照占用的空间更少。

使用RDB快照还会丢失数据吗?

RDB快照只保存了执行时刻的数据,因此在执行时刻之后的数据会丢失。因此需要和AOF日志配合使用,使丢失数据量降到最低。

Redis 4.0 中提出了一个混合使用 AOF 日志和内存快照的方法。简单来说,内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。