redis灵魂拷问:AOF文件可以保存RDB格式吗

目录

混合日志

RDB默认配置

RDB失败怎么办

 总结


AOF文件保存的是一条一条的写命令,它的优点很明显,保存了所有的写命令,可靠性高。但是缺点也很明显,在写操作频繁的redis使用场景,AOF文件会非常大,使用AOF进行故障恢复或者全量同步,需要依次执行每一条命令,效率很低。

RDB文件是一个内存快照,记录了redis某一时刻的数据快照,而不是一条条命令。而且RDB是二进制格式保存的,无论是写磁盘还是网络传输,效率都很高,所以RDB更适合做故障恢复和全量数据同步。但是RDB的缺点也很明显,它保存的只是某一时刻的数据快照,如果redis发生故障,上一次快照和故障之间的写命令就丢失了?

如下图,执行一个快照后,key2修改了,还没来得及下一次快照,redis发生故障,key2的这一次写操作就丢失了。

rdb

混合日志

redis4.0提出了混合使用AOF和RDB快照,在AOF文件中也可以记录RDB格式的日志。这个配置参数在redis.conf文件中,最新版本中默认是开启的。

# When rewriting the AOF file, Redis is able to use an RDB preamble in the
# AOF file for faster rewrites and recoveries. When this option is turned
# on the rewritten AOF file is composed of two different stanzas:
#
#   [RDB file][AOF tail]
#
# When loading Redis recognizes that the AOF file starts with the "REDIS"
# string and loads the prefixed RDB file, and continues loading the AOF
# tail.
aof-use-rdb-preamble yes

 我们看一下这个配置项上面的说明。上篇文章《redis灵魂拷问:聊一聊AOF日志重写》讲到了AOF重写。​AOF重写的时候会redis把AOF文件内容清空,然后记录一份RDB快照,这份数据以"REDIS"开头。记录RDB内容后,AOF文件会接着记录下次快照之前的写命令。这样就不用担心redis故障引起的数据丢失了。

在数据恢复时,redis首先会识别以"REDIS"开头的RDB日志并加载,然后再执行后面的写命令。

RDB默认配置

redis.conf中默认有下面的配置:

################################ SNAPSHOTTING  ################################
#
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#
#   Note: you can disable saving completely by commenting out all "save" lines.
#
#   It is also possible to remove all the previously configured save
#   points by adding a save directive with a single empty string argument
#   like in the following example:
#
#   save ""

save 900 1
save 300 10
save 60 10000

 上面的注解讲到,一个时间段内的请求数量决定了要不要写RDB日志。跟写AOF日志类似,redis主线程会fork一个bgsave子进程,fork完成之前主线程是阻塞的,而且fork之后bgsave子进程会跟主线程共用内存空间,如果这时有写请求到来,主线程只能通过CopyOnWrite来记录写数据。

RDB失败怎么办

默认情况下,如果bgsave子进程写RDB文件时出错了,redis会决绝新的写请求。比如redis因为内存原因执行快照失败,这时就不能接受新的写请求了,如果还想继续执行写命令,就把下面的参数设置为no,但这个可能不能解决根本问题,比如内存紧张导致的快照失败。

# By default Redis will stop accepting writes if RDB snapshots are enabled
# (at least one save point) and the latest background save failed.
# This will make the user aware (in a hard way) that data is not persisting
# on disk properly, otherwise chances are that no one will notice and some
# disaster will happen.
#
# If the background saving process will start working again Redis will
# automatically allow writes again.
#
# However if you have setup your proper monitoring of the Redis server
# and persistence, you may want to disable this feature so that Redis will
# continue to work as usual even if there are problems with disk,
# permissions, and so forth.
stop-writes-on-bgsave-error yes

 总结

1.redis写RDB跟写AOF日志类似,都需要fork子进程,fork过程都要阻塞主线程,如果这时写命令到来,主线程都需要COW的方式进行写操作。
2.AOF和RDB日志混合使用大大减少了AOF文件的大小,同时提高了全量数据同步或和故障恢复的效率。
3.RDB快照执行出错,redis默认会停止接收写请求,这个可以配置,但是要确定快照失败的原因。 


往期文章回顾:

redis灵魂拷问:聊一聊AOF日志重写

 《redis灵魂拷问:聊一聊redis底层数据结构

redis灵魂拷问:怎么搭建一个哨兵主从集群


   欢迎关注个人公众号

                                                                    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

君哥聊技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值