京东二面:Redis的RDB过程会卡顿一下嘛

690 阅读4分钟

前言

大家好,我是田螺

有位星球好友分享了一道京东面试题,我们一起来看一下:RDB过程会卡顿一下,原因了解吗?

这里就是考察reids的持久化机制,RDB。可以按这几个维度回答:

  • 讲讲RDB和卡顿的原因

  • 提到AOF,对比一下

  • RDB和AOF的对比

  • 如何选择RDB和AOF

  • 需要学习更多大厂面试真题,关注公众号:捡田螺的小男孩

1.RDB卡顿的原因

RDB是Redis的一种持久化机制。就是把内存数据以快照的形式保存到磁盘上。它记录的是某一时刻的数据

image.png

RDB持久化,是指在指定的时间间隔内,执行指定次数的写操作,将内存中的数据集快照写入磁盘中,它是Redis默认的持久化方式。执行完操作后,在指定目录下会生成一个dump.rdb文件,Redis 重启的时候,通过加载dump.rdb文件来恢复数据。RDB触发机制主要有以下几种:

如果用的是手动触发的save,会阻塞当前redis服务器

image.png

可以改用RDB通过bgsave命令,bgsave执行全量快照,可以避免阻塞主线程。basave命令会fork一个子进程,然后该子进程会负责创建RDB文件,而服务器进程会继续处理命令请求。也就是相当于异步进行。

虽然bgsave执行不会阻塞主线程,但是频繁执行全量快照也会带来性能开销。比如bgsave子进程需要通过fork操作从主线程创建出来,创建后不会阻塞主线程,但是创建过程是会阻塞主线程的。可以做增量快照

2. AOF 持久化

基于阻塞这个点,引出AOF,如果你比较熟悉AOF的话。

AOF不会阻塞当前命令,但是可能会阻塞下一个操作

Redis是基于内存的,如果Redis服务器挂了,数据就会丢失。除了RDB,Redis还提供了AOF(append only file) 的持久化

它,采用日志的形式来记录每个写操作,追加到AOF文件的末尾。Redis默认情况是不开启AOF的。重启时再重新执行AOF文件中的命令来恢复数据。它主要解决数据持久化的实时性问题。

AOF是执行完命令后才记录日志的。为什么不先记录日志再执行命令呢? 这是因为Redis在向AOF记录日志时,不会先对这些命令进行语法检查,如果先记录日志再执行命令,日志中可能记录了错误的命令,Redis使用日志回复数据时,可能会出错。

正是因为执行完命令后才记录日志,所以不会阻塞当前的写操作。但是会存在两个风险:

  1. 更执行完命令还没记录日志时,宕机了会导致数据丢失
  2. AOF不会阻塞当前命令,但是可能会阻塞下一个操作。

这两个风险最好的解决方案是折中妙用AOF机制的三种写回策略 appendfsync:

image.png

  • always,同步写回,每个子命令执行完,都立即将日志写回磁盘。
  • everysec,每个命令执行完,只是先把日志写到AOF内存缓冲区,每隔一秒同步到磁盘。
  • no:只是先把日志写到AOF内存缓冲区,有操作系统去决定何时写入磁盘。

always同步写回,可以基本保证数据不丢失,no策略则性能高但是数据可能会丢失,一般可以考虑折中选择everysec。

如果接受的命令越来越多,AOF文件也会越来越大,文件过大还是会带来性能问题。日志文件过大怎么办呢?AOF重写机制!就是随着时间推移,AOF文件会有一些冗余的命令如:无效命令、过期数据的命令等等,AOF重写机制就是把它们合并为一个命令(类似批处理命令),从而达到精简压缩空间的目的。

AOF重写会阻塞嘛? AOF日志是由主线程会写的,而重写则不一样,重写过程是由后台子进程bgrewriteaof完成。

3. AOF 和 RDB的对比

image.png

  • AOF的优点:数据的一致性和完整性更高,秒级数据丢失。
  • 缺点:相同的数据集,AOF文件体积大于RDB文件。数据恢复也比较慢。

而RDB

  • RDB的优点:与AOF相比,恢复大数据集的时候会更快,它适合大规模的数据恢复场景,如备份,全量复制等
  • 缺点:没办法做到实时持久化/秒级持久化。

Redis4.0开始支持RDB和AOF的混合持久化,就是内存快照以一定频率执行,两次快照之间,再使用AOF记录这期间的所有命令操作。

4. 如何选择RDB和AOF

  • 如果数据不能丢失,RDB和AOF混用
  • 如果只作为缓存使用,可以承受几分钟的数据丢失的话,可以只使用RDB。
  • 如果只使用AOF,优先使用everysec的写回策略。