理解与权衡Redis的两种持久化方式(RDB-AOF)

Posted ATFWUS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了理解与权衡Redis的两种持久化方式(RDB-AOF)相关的知识,希望对你有一定的参考价值。

在复习Redis相关知识时,系统整理了Redis持久化相关的知识点。



前言

Redis作为一个内存数据库,数据都保存在内存中,但是内存的数据是容易发生丢失的。Redis提供了持久化的机制,RDB(Redis DataBase)和AOF(Append Only File)。
下面Redis将数据保存到磁盘上的五个步骤:
前面三个步骤是Redis完成,后面两个步骤是操作系统完成。
所有和持久化相关的配置都在redis.conf中。

Redis官方对持久化机制的介绍见:https://redis.io/topics/persistence

下面翻译一下Redis官网对持久化机制的一个大体介绍:

Redis提供了一系列不同的持久性机制:

  • RDB(Redis Database):RDB持久化在指定的时间间隔执行数据集的快照。

  • AOF(Append Only File):AOF持久化记录服务器接收到的每个写入操作,这些操作将在服务器启动时再次执行,重建原始数据集。命令使用与Redis协议本身相同的格式,以仅附加的方式记录。当日志变得太大时,Redis能够在后台重写日志。

  • No persistence :如果希望,可以完全禁用持久化,只要服务器在运行,数据就一直存在。

  • RDB + AOF:可以在同一个实例中组合AOF和RDB。注意,在这种情况下,当Redis重新启动时,AOF文件将用于重建原始数据集,因为它保证是最完整的。

最重要的事情是理解RDB和AOF持久性之间的不同权衡。


Redis持久化之RDB(Redis DataBase)

1.理解RDB机制

指定的时间间隔内将内存中的数据集快照写入磁盘(Snapshot快照),它恢复时是将快照文件直接读到内存里。

Redis 会单独fork一个子进程来进行持久化

  • 首先将数据写入到一个临时文件中,等所有持久化过程全部结束了,再用临时文件替换上次持久化好的文件
  • 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。
  • 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
  • 但是最后一次持久化后的数据可能丢失。

2.RDB触发方式

save触发方式

执行save命令时只管保存,其它不管,全部阻塞。
该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。

bgsave触发方式

执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。阻塞只发生在fork阶段,一般时间很短。
可以通过lastsave命令获取最后一次成功执行快照的时间。

自动触发方式

自动触发是由配置文件来完成的。具体配置如下:

# save:用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。
# “save m n” 表示m秒内数据集存在n次修改时,自动触发bgsave。
# 如果不需要持久化,可以注释掉所有的 save 行来停用保存功能。
# 默认配置如下:
save 900 1 # 表示900 秒内如果至少有 1 个 key 的值变化,则保存
save 300 10
save 60 10000


# dbfilename :设置快照的文件名,默认是 dump.rdb
dbfilename dump.rdb

# dir:设置快照文件的存放路径,这个配置项是一个目录
dir ./

# 当Redis无法写入磁盘的话,直接关掉Redis的写操作。
# 推荐yes
stop-writes-on-bgsave-error yes

# 对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。
# 如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能。
# 推荐yes
rdbcompression yes

# 在存储快照后,还可以让redis使用CRC64算法来进行数据校验,
# 但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
# 推荐yes
rdbchecksum yes

动态停止RDB的方式:

#save后给空值,表示禁用保存策略
redis-cli config set save "" 

3.RDB的优劣势

优势

  • 适合大规模的数据恢复
  • 对数据完整性和一致性要求不高更适合使用
  • 节省磁盘空间
  • 恢复速度快

劣势

  • Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑。
  • 虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。
  • 在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。

Redis持久化之AOF(Append Only File)

1.理解AOF机制

以日志的形式来记录每个写操作(增量保存机制),将Redis执行过的所有写指令记录下来(读操作不记录), 只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据。通俗理解就是日志记录。

redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

持久化流程:

(1)客户端的请求写命令会被append追加到AOF缓冲区内;
(2)AOF缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中;
(3)AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;
(4)Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;

2.重写(Rewrite)

AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制, 当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩, 只保留可以恢复数据的最小指令集。
使用如下命令:

bgrewriteaof

重写原理

AOF文件持续增长而过大时,会fork出一条新进程来将文件重写。先写临时文件最后再rename。
redis4.0版本后,重写的原理是:将rdb对的快照,以二进制的形式附在新的aof的头部,作为已有的历史数据,替换掉原来的流水账操作。

重写虽然可以节约大量磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis要满足一定条件才会进行重写。

# 设置重写的基准值,文件达到100%时开始重写(文件是原来重写后文件的2倍时触发)
auto-aof-rewrite-percentage
# 设置重写的基准值,最小文件64MB。达到这个值开始重写。
auto-aof-rewrite-min-size
# 如果值为yes 不写入aof文件 只写入缓存 用户请求不会阻塞 在这段时间如果宕机会丢失这段时间的缓存数据。数据安全性降低 性能提高
# 如果值为no,会把数据写入磁盘,但是遇到重写操作,可能会发生阻塞。 数据安全性提高 性能降低
no-appendfsync-on-rewrite yes 

重写流程

当使用bgrewriteaof命令后,重写流程如下:
(1)判断是否有bgsavebgrewriteaof还未结束,如果有,则等待其结束再执行。
(2)主进程fork出子进程进行重写操作。
(3)子进程将redis内存中数据保存到临时文件,与此同时,新的客户端写请求会写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整以及文件生成的过程中新的数据修改操作不会丢失。
(4)子进程写完新的AOF文件后,通知父进程。
(5)主进程把aof_rewrite_buf中的数据写入到心的AOF文件。
(6)使用新的AOF文件覆盖旧的AOF文件,完成该次的AOF重写操作。

3.AOF同步频率

# 始终同步,每次Redis的写入都会立刻记入日志;性能较差但数据完整性比较好
appendfsync always
# 每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
appendfsync everysec
# redis不主动进行同步,把同步时机交给操作系统。
appendfsync no

同步频率优点缺点
always不会丢失数据IO开销大
everysecIO开销低丢失1s数据
no无额外IO开销容易丢失数据

4.相关配置说明

  • AOF默认不开启,修改配置文件开启。
# 改为yes开启
appendonly no
  • 可以在redis.conf中配置文件名称,默认为 appendonly.aof

  • AOF文件的保存路径,同RDB的路径一致。

  • AOF的备份机制和性能虽然和RDB不同, 但是备份和恢复的操作同RDB一样,都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载。

AOF和RDB同时开启,系统默认取AOF的数据(数据不会存在丢失)

5.AOF的优劣势

优势

  • AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据。
  • AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。
  • 可读的日志文本,通过操作AOF文件可以处理误操作。
  • AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损。

劣势

  • 比起RDB占用更多的磁盘空间。
  • 恢复备份速度要慢。
  • 每次读写都同步的话,有一定的性能压力。
  • 存在个别Bug,造成恢复不完全。

RDB和AOF的权衡

Redis官网的建议

  • RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储

  • AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.

  • Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大

  • 只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.

  • 同时开启两种持久化方式

    • 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据, 因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.
  • RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?

    • 建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份), 快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。
  • 如果对数据不敏感,可以选单独用RDB。

性能建议

  • 1.RDB文件一般只做后备用途,建议只在Slave上持久化RDB数据文件,一般15分钟备份一次就足够了。
  • 2.如果硬盘容量允许,尽量减少AOF rewrite的频率,AOF重写的基础大小是64M,实际生产环境中过小,可以设到5G以上。
  • 3.默认超过原大小100%大小时重写,可以做适当的修改。

参考

  • 《Redis设计与实现》
  • 《Redis开发与运维》
  • 《深入理解Redis》
  • https://redis.io/topics/persistence

ATFWUS 2021-09-29

以上是关于理解与权衡Redis的两种持久化方式(RDB-AOF)的主要内容,如果未能解决你的问题,请参考以下文章

Redis持久化的两种方式

redis持久化的两种方式

redis 持久化的两种方式

Redis 持久化的两种方式

redis持久化的两种方式RDB和AOF

redis 两种持久化方式对比以及数据恢复