• AOF记录的是操作命令,如果日志很多,那么恢复时就比较慢。
  • 所谓内存快照,就是指内存中的数据在某一个时刻的状态记录。

三个问题

  • 对哪些数据做快照?这关系到快照的执行效率问题
  • 做快照时,数据还能被增删改吗?这关系到 Redis 是否被阻塞,能否同时正常处理请求。
  • 可以每秒做一次快照吗?

给哪些内存数据做快照?

  • Redis执行的是全量快照,一次性记录了所有数据,但是也会产生更大磁盘开销,因为产生的RDB文件更大。
  • Redis提供了两个命令,savebgsave
  • save:在主线程中执行,会导致阻塞;
  • bgsave:创建一个子进程,专门用于写入 RDB 文件,避免了主线程的阻塞,这也是 Redis RDB 文件生成的默认配置。

做快照时数据还能增删改吗?

  • Redis 借助操作系统提供的写时复制技术(Copy-On-Write, COW),在执行快照的同时,正常处理写操作。
  • 由于bgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。
  • 如果主线程对这些数据也都是读操作,那么,主线程和 bgsave 子进程相互不影响。
  • 如果主线程要修改一块数据,那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。
  • 总结:子进程直接读父进程内存数据,发生写操作时,复制一份副本,放到子进程自己的物理内存空间。子进程把副本数据写入RDB为文件。

可以每秒做一次快照吗?

  • 频繁执行全量快照会带来两方面开销:
  • 写RDB文件到磁盘,会给磁盘带来较大压力。
  • 虽然bgsave不阻塞主线程,但是fork创建过程本身是会阻塞主线程的。主线程内存越大阻塞时间越长。
  • 可以使用增量快照,Redis 4.0提供了混合使用 AOF 日志和内存快照的策略。
  • 在两次全量快照之间,使用AOF日志记录操作命令,在第二次全量快照后,清除之前的AOF日志。