Redis7.0 持久化AOF与RDB

在这里插入图片描述
  持久性是指将数据写入持久存储器,如固态硬盘(SSD)。Redis提供了一系列持久性选项。其中包括:

  • RDB:RDB持久性以指定的时间间隔执行数据集的时间点快照。
  • AOF(仅附加文件):AOF持久性记录服务器接收到的每个写入操作。然后,可以在服务器启动时再次重播这些操作,从而重建原始数据集。使用与Redis协议本身相同的格式记录命令。
  • No persistence:可以完全禁用持久性。
  • RDB+AOF:也可以将AOF和RDB组合在同一个实例中。如果不想考虑这些不同的持久性策略之间的权衡,你可能想考虑Redis Enterprise的持久性选项,它可以使用UI预先配置。

1、RDB

在这里插入图片描述
  RDB持久性以指定的时间间隔执行数据集的时间点快照。在指定的时间间隔内将内存中的所有数据集全量快照Snapshot写入磁盘dump.rdb文件,它恢复时再将硬盘快照文件直接读回到内存里。

​  每当Redis需要将数据集dump到磁盘时,Redis 会fork一个子进程,子进程将数据集写入一个临时的RDB文件。当子进程完成新的RDB文件的编写后,它会替换旧的RDB,所以RDB持久化方式可以最大化redis的性能。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。

**注意:**生产环境中不可以把备份文件dump.rdb.bak和Reids 服务器放在同一台机器,必须分开各自存储,以防生产机物理损坏后备份文件也挂了。

1.1 触发配置

​  在Redis.conf 配置文件中的SNAPSHOTTING下配置save参数,来实现自动触发Redis的RDB持久化条件。比如“save m n”:表示m秒内数据集存在n次修改时,自动触发bgsave

1.1.1 触发条件

  可以通过config get save获取当前自动触发快照的配置,注意:save配置项中的时间指的是多久检查一次,即上一次执行bgsave命令到现在的时间间隔,而非多少时间之内完成多少key变化。

$ redis > config get save
1) "save"
2) "5 2"

$ redis > config set save "" #启动期间开启关闭rdb
  • Redis 6.0.19 以下

save 900 1:每隔900s(15min)检查一次,如果有超过1个key 发生了变化,就写一份新的RDB文件

save 300 10:每隔300s(5min)检查一次,如果有超过10 个key 发生了变化,就写一份新的RDB文件

save 60 10000:每隔60s(1min)检查一次,如果有超过10000个key 发生了变化,就写一份新的RDB文件

  • Redis 6.2 及Redis 7

​  redis6.2开始,默认配置:save 3600 1 300 100 60 10000:每隔3600s(1h),如果有超过1个key 变化,就写一份新的RDB文件;每隔300s(5min),如果有超过100个key 变化,就写一份新的RDB文件;每隔60s(1min),如果有超过10000个key 变化,就写一份新的RDB文件。若增添自定义规则,将覆盖默认的规则。

#6.0.18
################################ 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 behavior 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


#6.2.11
################################ SNAPSHOTTING  ################################

# Save the DB to disk.
#
# save <seconds> <changes>
#
# Redis will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.
#
# Snapshotting can be completely disabled with a single empty string argument
# as in following example:
#
# save ""
#
# Unless specified otherwise, by default Redis will save the DB:
#   * After 3600 seconds (an hour) if at least 1 key changed
#   * After 300 seconds (5 minutes) if at least 100 keys changed
#   * After 60 seconds if at least 10000 keys changed
#
# You can set these explicitly by uncommenting the three following lines.
#
# save 3600 1
# save 300 100
# save 60 10000

#7.0.10
################################ SNAPSHOTTING  ################################

# Save the DB to disk.
#
# save <seconds> <changes> [<seconds> <changes> ...]
#
# Redis will save the DB if the given number of seconds elapsed and it
# surpassed the given number of write operations against the DB.
#
# Snapshotting can be completely disabled with a single empty string argument
#
# save "" #完全禁用快照
#
# Unless specified otherwise, by default Redis will save the DB:
#   * After 3600 seconds (an hour) if at least 1 change was performed
#   * After 300 seconds (5 minutes) if at least 100 changes were performed
#   * After 60 seconds if at least 10000 changes were performed
#
# You can set these explicitly by uncommenting the following line.
#
# save 3600 1 300 100 60 10000

1.1.2 禁用快照功能

  • 动态停止RDB保存规则:redis-cli config set save ""
  • 修改配置文件:在SNAPSHOTING中设置save ""
################################ SNAPSHOTTING  ################################
...
# Snapshotting can be completely disabled with a single empty string argument
#使用单个空字符串参数可以完全禁用快照
save ""

1.1.3 dump文件位置

​  可以使用CONFIG GET dir指令获取快照保存目录,注意:一般需要指定绝对路径,默认./那么文件地址为启动命令行所在的目录,比如配置了自启动,那么快照将保存到/路径下。

# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
#指定文件夹而非文件名
dir ./

1.1.4 dump文件名

​  为了后面的集群配置方便,一般需要自定义配置,如:dump6379.rdb

# The filename where to dump the DB
dbfilename dump.rdb

1.1.5 其他配置项

  • stop-write-on-bgsave-error:推荐默认yes,当Redis无法写入磁盘的话,直接关掉Redis的写操作。如果配置成no,表示不在乎数据不一致或者有其他的手段发现和控制这种不一致,那么在快照写入失败时,也能确保redis继续接受新的写请求。
  • rdbcompression:默认yes,对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。 如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能。
  • rdbchecksum:默认yes,在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
  • rdb-del-sync-files:用于控制在执行 RDB 持久化时是否同时删除旧的 RDB 快照文件,以便于在需要时可以回滚到旧的数据。默认情况下no,此选项是禁用的。

1.2 快照指令

  • 执行快照指令

  Redis提供了触发生成快照的两个指令:savebgsave。但是在主程序中执⾏时,save阻塞当前redis服务器,直到持久化工作完成,执行save命令期间,Redis不能处理其他命令,所以线上禁止使用SAVE

  BGSAVE正常情况下,会立即返回OK代码:“Background saving started”,不阻塞响应客户端请求并完成快照。用fork复制一个与当前进程完全相同的子进程,子进程数据(变量、环境变量、程序计数器等) 都和父进程一致。父级继续对外提供服务,子级将DB保存在磁盘上,一般情况父进程和子进程会共用同一段物理内存,但这期间若有数据更新,就会触发写时复制,来保证快照数据的一致性(RDB快照数据对应fork时刻)。当有后台或非后台保存进程在运行,特别是AOF重写,则可能会返回错误;可以使用bgsave schedule命令来延迟bgsave,等待AOF重写完成后再执行。
在这里插入图片描述

写时复制机制:

​  fork()之后,kernel把父进程中所有的内存页的权限都设为read-only,然后子进程的地址空间指向父进程,而不是直接复制内存中的数据。当父子进程都只读内存时,相安无事。当父进程进行写操作时,且CPU硬件检测到内存页是read-only的,于是触发页异常中断(page-fault),陷入kernel的一个中断例程。中断例程中,父进程通过kernel把触发的异常的页复制得到一份新的内存页,并从原内存页copy所有数据,之后父进程就在新的内存页上进行操作。而原内存页就变成了子进程的专属内存页。因此,写时复制技术确保了快照的一致性,并且保证了Redis在持久化数据时不会影响到其他客户端对内存数据的访问。

  使用LASTSAVE命令来检查上次执行快照保存的时间戳,来判断快照执行是否成功。

redis > lastsave
(integer) 1680541205

#linux时间戳转换
[root@lightrain /]# date -d @1680541205
Tue Apr  4 01:00:05 CST 2023
  • 修复快照

  通过redis-check-rdb dump.rdb完成对快照简单修复,避免因小问题导致整个kau’zikauzi好不可用。

[root@lightrain /]# redis-check-rdb /opt/software/redis-7.0.10/dump.rdb 
[offset 0] Checking RDB file /opt/software/redis-7.0.10/dump.rdb
[offset 27] AUX FIELD redis-ver = '7.0.10'
[offset 41] AUX FIELD redis-bits = '64'
[offset 53] AUX FIELD ctime = '1680541205'
[offset 68] AUX FIELD used-mem = '931472'
[offset 80] AUX FIELD aof-base = '0'
[offset 82] Selecting DB ID 0
[offset 122] Checksum OK
[offset 122] \o/ RDB looks OK! \o/
[info] 4 keys read
[info] 0 expires
[info] 0 already expired

1.3 触发快照指令

  • flushall/flushdb命令也会产生快照文件,但是这个快照没有意义,因为是空数据,这可能是Redis的设计缺陷或者为了保持一致性。
  • 执行shutdown且没有设置开启AOF持久化,也会自动触发bgsave
  • 主从复制时,主节点自动触发

1.4 优劣势

优势

  • 按照业务定时备份:RDB是一种非常紧凑的单文件时间点表示Redis数据的方式,非常适合备份。将RDB文件存档,例如每小时存档最近24小时的数据,每天存档30天的数据。这样,可以在灾难发生时轻松恢复不同版本的数据集,并传输到远程数据中心或Amazon S3。
  • 持久化性能高:RDB还可以优化Redis性能,因为Redis父进程所需的唯一工作是fork出一个子进程来完成所有工作,父进程不会执行任何磁盘I/O等操作,且支持写时复制提高了效率并节省了空间。
  • 适合大规模数据恢复,加载速度快:相对于AOF,RDB允许使用大数据集进行更快速的重启,重启时会默认使用指定保存位置的快照文件。
  • 支持部分同步:在副本中,RDB支持重启和故障转移后的部分重新同步。

劣势

  • 数据丢失、安全性不高:Redis因任何原因停止工作而非正常关闭,就会损失当前时间到最近一次快照的数据。
  • 内存和IO压力高:RDB需要经常fork子进程来进行全量快照保存到硬盘上,当数据集比较大的时,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级不能相应客户端请求。AOF也需要fork,但频率较低,可以调整要重写日志的频率,而不需要对持久性进行任何权衡。

2、AOF

​  快照功能并不是完全持久化的durable: 若因某些原因而造成故障停机(kill -9模拟), 那么服务器将丢失最近写入且未保存到快照中的数据。 从 1.1 版本增加了 AOF 持久化,其默认不开启。开启后,以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),并被追加到 AOF(appendonly.aof)文件的末尾而不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
在这里插入图片描述
​  写命令到达Redis Server 以后并不是直接写入AOF文件,而是先放入AOF缓存区进行保存(实际上是内存中的一片区域),目的是当这些命令达到一定量以后再写入磁盘,避免频繁的磁盘IO操作。AOF缓冲会根据AOF缓冲区写回策略将命令写入磁盘上的AOF文件。

2.1 同步策略

  • appendfsync always:写操作立即被追加到 AOF 文件中,这种写回策略能够保证最高的数据安全性,数据基本不丢失。由于fsync(file synchronize)可能会阻塞主线程,所以会对 Redis 的性能和可用性产生影响。
  • appendfsync everysec:每秒钟将 AOF 缓存中的所有写操作都写入 AOF 文件中。可以减少写入 AOF 文件的次数,从而提高 Redis 的性能,同上也可能出现阻塞问题。
  • appendfsync no:写命令执行完,只是先把日志写到AOF文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。这种性能最好,但是因宕机等原因损失的数据最多。
# The fsync() call tells the Operating System to actually write data on disk
# instead of waiting for more data in the output buffer. Some OS will really flush
# data on disk, some other OS will just try to do it ASAP.

# Redis supports three different modes:

# no: don't fsync, just let the OS flush the data when it wants. Faster.
# always: fsync after every write to the append only log. Slow, Safest.
# everysec: fsync only one time every second. Compromise.

# The default is "everysec", as that's usually the right compromise between
# speed and data safety. It's up to you to understand if you can relax this to
# "no" that will let the operating system flush the output buffer when
# it wants, for better performances (but if you can live with the idea of
# some data loss consider the default persistence mode that's snapshotting),
# or on the contrary, use "always" that's very slow but a bit safer than
# everysec.

# More details please check the following article:
# http://antirez.com/post/redis-persistence-demystified.html

# If unsure, use "everysec".

# appendfsync always
appendfsync everysec
# appendfsync no

2.2 AOF重写

​  由于AOF会以追加的方式记录每一条redis的写命令,因此随着Redis处理的写命令增多,AOF文件也会变得越来越大,命令回放的时间也会增多,为了解决这个问题,Redis引入了AOF rewrite机制(简称AOFRW)。将AOF不是对源文件进行内容整理,而是直接读取服务器现有键值,只保留可以恢复数据的最小指令集。可以手动执行bgrewirteaof来重写或生成AOF,也可以通过配置完成自动触发:

# Automatic rewrite of the append only file.
# Redis is able to automatically rewrite the log file implicitly calling
# BGREWRITEAOF when the AOF log size grows by the specified percentage.
#
# This is how it works: Redis remembers the size of the AOF file after the
# latest rewrite (if no rewrite has happened since the restart, the size of
# the AOF at startup is used).
#
# This base size is compared to the current size. If the current size is
# bigger than the specified percentage, the rewrite is triggered. Also
# you need to specify a minimal size for the AOF file to be rewritten, this
# is useful to avoid rewriting the AOF file even if the percentage increase
# is reached but it is still pretty small.
#
# Specify a percentage of zero in order to disable the automatic AOF
# rewrite feature.

#注意 ,同时满足才会触发,
#根据上次重写后的aof大小,判断当前aof大小是不是增长了1倍,
#重写时满足的最小文件大小
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

2.2.1 Redis 6/7 策略

  • Redis 6及以前

  当AOFRW被触发执行时,Redis首先会fork一个子进程进行后台重写操作,该操作会将执行fork那一刻Redis的数据快照全部重写到一个名为temp-rewriteaof-bg-pid.aof的临时AOF文件中。 由于重写操作为子进程后台执行,主进程在AOF重写期间依然可以正常响应用户命令。因此,为了让子进程最终也能获取重写期间主进程产生的增量变化,主进程除了会将执行的写命令写入aof_buf(保证原有的AOF可用性,避免重写出现问题),还会写一份到aof_rewrite_buf中进行缓存。在子进程重写的后期阶段,通知主进程将aof_rewrite_buf中累积的数据使用pipeline发送给子进程,子进程会将这些数据追加到临时AOF文件中。

​ 当主进程承接了较大的写入流量时,aof_rewrite_buf中可能会堆积非常多的数据,导致在重写期间子进程无法将aof_rewrite_buf中的数据全部消费完。此时,aof_rewrite_buf剩余的数据将在重写结束时由主进程进行处理。当子进程完成重写操作并退出后,主进程会在backgroundRewriteDoneHandler 中处理后续的事情。首先,将重写期间aof_rewrite_buf中未消费完的数据追加到临时AOF文件中。其次,当一切准备就绪时,Redis会使用rename操作将临时AOF文件原子的重命名为server.aof_filename(AOF文件名),此时原来的AOF文件会被覆盖。至此,整个AOFRW流程结束。
在这里插入图片描述

AOFRW缺点:

  在AOFRW期间,主进程会将fork之后的数据变化写进aof_rewrite_buf中,aof_rewrite_buf和aof_buf中的内容绝大部分都是重复的,因此这将带来额外的内存冗余开销。aof_buf中的数据最终会被写入到当前使用的旧AOF文件中,产生磁盘IO。同时,aof_rewrite_buf中的数据也会被写入重写生成的新AOF文件中,产生磁盘IO。因此,同一份数据会产生两次磁盘IO

  • Redis 7以后

​  引入MP-AOF(multi part AOF):将原来的单个AOF拆分成多个AOF文件,并分为三种类型,分别为:BASE:基础AOF,一般由子进程通过重写产生,最多只有一个;INCR:增量AOF,一般会在AOFRW开始执行时被创建,该文件可能存在多个;HISTORY:每次AOFRW成功完成时,本次重写之前对应的BASE和INCR AOF都将变为HISTORY,之后被自动删除。引入了一个manifest(清单)文件来跟踪、管理这些AOF。同时,为了便于AOF备份和拷贝,我们将所有的AOF文件和manifest文件放入一个单独的文件夹中,文件夹名由appenddirname配置(Redis 7.0新增配置项)决定。

​  MP-AOF版AOFRW的大致流程:在开始时依然fork一个子进程进行重写操作,在主进程中,我们会同时打开一个新的INCR类型的AOF文件,在子进程重写操作期间,所有的数据变化都会被写入到这个新打开的INCR AOF中。子进程的重写操作完全是独立的,重写期间不会与主进程进行任何的数据和控制交互,最终重写操作会产生一个BASE AOF。新生成的BASE AOF和新打开的INCR AOF就代表了当前时刻Redis的全部数据。AOFRW结束时,主进程会负责更新manifest文件,并完成新的BASE AOFINCR AOF信息添加,将过去的BASE AOFINCR AOF标记为HISTORY(会被Redis异步删除)。当manifest文件更新完毕,就标志整个AOFRW流程结束。
在这里插入图片描述
​​  所以在AOFRW期间不再需要aof_rewrite_buf,因此去掉了对应的内存消耗。同时,主进程和子进程之间也不再有数据传输和控制交互,因此对应的CPU开销也全部去掉。六个pipe对应的代码也全部删除,使得AOFRW逻辑更加简单清晰。

2.2.2 Redis 6/7 AOF文件位置、文件名

  • Redis 6及以前,AOF保存文件的位置和RDB保存文件的位置一样,都是通过redis.conf配置文件的dir配置,并通过appendfilename配置项指定文件名。
# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
$aof文件也会被创建到这个文件夹中
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir ./


# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"
  • 在MP-AOF中,文件夹地址由appenddirname+dir两个配置项决定;使用basename.suffix的方式命名多个AOF文件,basename部分也由appendfilename配置决定,suffix则由三个部分组成,格式为seq.type.format ,其中:seq为文件的序号,由1开始单调递增,BASE和INCR拥有独立的文件序号;type为AOF的类型,表示这个AOF文件是BASE还是INCR;format表示AOF的编码方式,由于Redis支持 RDB preamble(aof-use-rdb-preamble)机制,所以BASE AOF可能是RDB格式编码也可能是AOF格式编码。
#指定sof文件目录由appenddirname和dir配置项共同决定
#/opt/software/redis 7.0.10/myredis/appendonlydir
dir /opt/software/redis 7.0.10/myredis
appenddirname "appendonlydir"
# For example, if appendfilename is set to appendonly.aof, the following file
# names could be derived:
#
# - appendonly.aof.1.base.rdb as a base file.
# - appendonly.aof.1.incr.aof, appendonly.aof.2.incr.aof as incremental files.
# - appendonly.aof.manifest as a manifest file.
appendfilename "appendonly.aof"

#当使用appendfilename默认配置时(默认为appendonly.aof),BASE、INCR和manifest文件的可能命名如下:
appendonly.aof.1.base.rdb // 开启RDB preamble
appendonly.aof.1.base.aof // 关闭RDB preamble
appendonly.aof.1.incr.aof
appendonly.aof.2.incr.aof
appendonly.aof.manifest #清单文件

2.2.3 重写阻塞问题

​  AOF重写时是否会阻塞线程取决于AOF的fsync策略和no-appendfsync-on-rewrite配置项:如果AOF的fsync策略是always或者everysec,那么AOF重写时可能会阻塞主线程,因为主线程会监控fsync的执行进度,如果发现上一次的fsync操作还没有返回,那么主线程就会阻塞。

​  如果no-appendfsync-on-rewrite配置项是yes,那么AOF重写时不会阻塞主线程。但是这样做有一个潜在的风险,就是如果在AOF重写期间Redis宕机了,那么AOF的数据便会丢失,可靠性下降。如果no-appendfsync-on-rewrite配置项是no,那么AOF重写时可能会阻塞主线程,因为主线程会继续执行fsync操作,这个时候就会产生IO竞争,有可能阻塞主线程。

2.3 配置项

  • appendonly:用来开启或关闭AOF持久化的,设置为no禁用模式下,仍可以通过bgrewriteaof来生成aof文件。
#在redis启动期间可以通过指令来临时修改
$ redis > config set appendonly yes/no #开启关闭aof
$ redis > config set save ""           #开启关闭rdb
  • aof-timestamp-enabled:支持在AOF中记录时间戳注释,以支持从特定时间点恢复数据。但会改变AOF的格式,可能与现有的AOF解析器不兼容。
# Redis supports recording timestamp annotations in the AOF to support restoring
# the data from a specific point-in-time. However, using this capability changes
# the AOF format in a way that may not be compatible with existing AOF parsers.
aof-timestamp-enabled no
  • aof-use-rdb-preamble:开启AOF模式混合持久化,no表示禁用。在Redis 6及以前,aof-use-rdb-preamble默认值是yes,控制AOF文件的前缀部分使用RDB格式,而后为AOF格式,这样做的好处是可以加快AOF文件的重写和加载速度,以及节省磁盘空间。而在Redis 7 中引入MP AOF机制后,它用于表示base aof的采用的格式(RDBAOF),而不再是作为AOF文件的前缀。
# Redis can create append-only base files in either RDB or AOF formats. Using
# the RDB format is always faster and more efficient, and disabling it is only
# supported for backward compatibility purposes.
aof-use-rdb-preamble yes
  • no-appendfsync-on-rewrite:默认yes,进行BGSAVE/BGREWRITEAOF时,执行AOF重写操作时主进程将不会进行fsync()刷新内存新命令到AOF文件,而是将其暂存于重写缓冲区中,等待BGSAVEBGREWRITEAOF结束后进行fsync刷盘到AOF文件,避免重写时因为磁盘IO造成阻塞;如果应用对安全要求比较高,建议设置为no, 防止数据丢失。
# Note that if the AOF file will be found to be corrupted in the middle
# the server will still exit with an error. This option only applies when
# Redis will try to read more data from the AOF file but not enough bytes
# will be found.
aof-load-truncated yes
  • auto-aof-rewrite-percentageauto-aof-rewrite-min-size:开启重写和触发AOF重写机制体条件。
auto-aof-rewrite-percentage 100 # 触发重写百分比 (如果设置为0,将禁用AOF自动重写功能)
auto-aof-rewrite-min-size 64mb  # 触发自动重写的最低文件体积(小于64MB不自动重写)
  • aof-load-truncated:当Redis启动时,发现AOF文件出现末尾截断,这时是继续加载文件还是报错退出。若是中间部分出现错误,则无论配置了yes,也会直接报错退出。
# Note that if the AOF file will be found to be corrupted in the middle
# the server will still exit with an error. This option only applies when
# Redis will try to read more data from the AOF file but not enough bytes
# will be found.
aof-load-truncated yes

2.4 恢复与RDB混合配合使用

# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is the file
# with the better durability guarantees.
appendonly no

​​  重启时同时存在rdb和aof文件时,redis会优先使用aof文件来恢复启动,因为aof文件记录了每一个写操作,能够重建原始的数据集。如果aof文件损坏或者不存在,那么可以使用rdb文件来恢复启动,因为rdb文件是数据集的定时快照。恢复启动的步骤如下:

  • 如果只有rdb文件,那么直接启动redis,它会自动加载rdb文件。
  • 如果只有aof文件,那么需要在配置文件中开启aof功能,然后启动redis,它会自动加载aof文件。
  • 如果有rdb和aof文件,那么需要在配置文件中开启aof功能,然后启动redis,它会忽略rdb文件,只加载aof文件。
  • 如果aof受损,可以通过redis-check-aof --fix <filename>进行修复

AOF与RDB混合使用

​  RDB镜像做全量持久化,AOF做增量持久化。因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。

2.5 优劣势

优势:

  • AOF比RDB更持久:可以通过不同的fsync写回策略来提供更好的持久性保障,包括不进行fsync、每秒进行fsync、每次查询都进行fsync。默认情况下,AOF使用每秒fsync策略,仍然能保持很好的写入性能。fsync是使用后台线程执行的,当没有进行fsync时,主线程会努力执行写入操作,因此只会损失一秒钟的写入操作。
  • 仅追加型日志,可以快速修复:AOF日志是一个仅追加的日志,因此不会出现寻道问题,也不会在停电时不会出损坏问题。即使由于某种原因(磁盘已满或其他原因),日志以半写命令结束,redis-check-aof工具也能很容易地修复它。
  • 自动重写压缩:Redis能够在AOF文件过大时自动在后台重写它。重写是完全安全的,因为当Redis继续追加到旧文件时,会用创建当前数据集所需的最小操作集生成一个全新的文件,一旦第二个文件准备好,Redis就会切换这两个文件并开始追加到新文件。
  • 文件语法易于维护:AOF包含一个易于理解和解析的格式,记录了一个接一个的所有操作的日志。可以轻松导出AOF文件。即使您意外地使用FLUSHALL命令刷新了所有内容,只要在此期间没有执行日志重写,仍然可以通过停止服务器、删除最新命令并重新启动Redis来保存数据集。

劣势:

  • 数据量较大,恢复速度较慢:对于同一数据集,AOF文件通常比等效的RDB文件大,恢复速度也相对较慢。
  • 写回速度较慢:根据所使用的 fsync 写回策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。
  • 出现内存冗余:在Redis 7.0以下版本,如果一个写入命令在重写过程中被执行,它会被缓存到内存中(可能会使用大量内存),并写入新的AOF文件。当重写完成后,Redis会将内存中的缓存数据再写入旧的AOF文件,这样就可以保证新旧两个AOF文件中的数据都包含这个写入命令。因此,每个写入命令都会被写入磁盘两次,一次写入新的AOF文件,一次写入旧的AOF文件。
  • 在Redis 7.0以下版本,重写结束后,Redis会冻结对新AOF文件的写入和fsyncing这些写入命令。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值