zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

Redis——redis的rdb和aof持久化

Redis 持久 RDB AOF
2023-09-11 14:16:28 时间

redis持久化选项:

  • 不使用持久化:完全禁用任何持久化;
  • RDB:以指定的时间间隔对数据进行时间点快照;
  • AOF:以追加的方式记录服务器收到的每个写操作,服务器启动时重放以恢复数据;使用与redis协议本身相同的格式进行记录,aof文件过大时redis可以在后台重写aof文件;
  • RDB+AOF:同时使用RDB和AOF持久化,利用各自的长处;服务器启动时aof文件用来重建数据;

rdb和aof优缺点:

rdb优点:

  • 是一个非常紧凑的时间点单文件,非常适用于备份;
  • 非常适用于灾难回复,单一压缩文件可以传到远端数据中心;
  • 最大限度地提高redis性能,父进程只需创建一个子进程处理,自己不需要I/O操作;
  • 大数据量重启比aof快;
  • 在副本上支持重启和故障转移后的部分同步;

rdb缺点:

  • 定时rdb,宕机会丢失上次rdb到当前宕机时间的数据;
  • rdb需要fork()子进程持久化,数据量大时经常fork()耗时影响性能,redis可能会停止为客户端服务几毫秒甚至一秒钟;

aof优点:

  • 保存数据更完整,有3种策略,默认每秒一次,宕机只损失一秒数据;
  • 只追加日志,停电不会损坏,即使最后写入损坏了也可用redis-check-aof程序修复;(如果aof文件中间损坏最好定位位置手动修改)
  • 日志过大redis将自动重写,重写是完全安全的;
  • aof格式便于理解和解析,顺序写入操作日志,可以手动修改;(甚至,不小心FLUSHALL后在aof重写前关停服务将aof最后的清空命令删除再重启可以回复数据)

aof缺点:

  • 文件比rdb大;
  • 性能比rdb稍差;
  • (7.0版本之前)重写过程中有对数据库的写操作,aof会使用大量内存;
  • (7.0版本之前)重写过程中到达的所有写命令会被写入磁盘两次;
  • (7.0版本之前)redis会冻结写入并在重写结束时将这些命令同步到新aof文件中;

配置文件redis.conf(更新至redis-7.0.2)

SNAPSHOTTING(rdb)

save 900 1 在900s内至少有1条数据变化就保存到文件。
save 300 10 在300s内至少有10条数据变化就保存到文件。
save 60 10000 在60s内至少有10000条数据变化就保存到文件。

默认情况下redis将保存DB,可以使用空字符串禁用快照:save ""

语法改为 save <seconds> <changes> [<seconds> <changes> ...] 多条配置放到一行,默认配置为save 3600 1 300 100 60 10000,1小时至少1条或5分钟至少100条或60秒至少10000条变动。

stop-writes-on-bgsave-error yes 如果最后一次rdb失败redis将停止接受写入,如果后台保存进程再次开始工作redis会自动接受写入。

rdbcompression yes 保存rdb时使用lzf压缩算法压缩。(关闭会节省一些cpu,但会加大存储空间)

rdbchecksum yes 在文件最后添加CRC64校验,使得文件更抗损坏,但是保存和读取rdb文件时有10%性能消耗。(当rdb文件创建的时候,redis会将checksum置0禁用checksum,告诉加载代码跳过检查)

sanitize-dump-payload no 当加载rdb或者restore负载时,启用或者禁用对ziplist或者listpack的完整清理检查,这减少了在处理命令时发生断言或者崩溃的几率;该项有三个值可用:no:永不运行完整清理检查,yes:总是运行完整清理检查,clients:仅对用户连接进行完整清理检查,以下情况除外:从master收到的RDB文件和RESTORE命令,或者带有skip-sanitize-payload ACL标志的客户端;(默认应该是“clients”,但由于目前它通过MIGRATE影响了集群重新分片,所以暂时默认值是“no”)

dbfilename dump.rdb 保存的rdb文件名字。

rdb-del-sync-files no 删除没有开启持久化实例中的用于同步的rdb文件;默认该功能是关闭的,有时候出于法规或者安全考虑,master存储在磁盘上用于给副本同步使用的rdb文件,或者副本存储在磁盘上用于初始化时使用的rdb文件,都应该尽快删除;(该配置只有在RDB和AOF都关闭时才生效,否则被忽略)(另一种有相同效果的方法就是主从之间使用无磁盘同步)

dir ./ 保存的RDB文件目录,文件名字由dbfilename指定,aof也用该目录,并且必须是个文件夹。

手动RDB:

./redis-cli执行save或者bgsave,bgsave不会长时间阻塞。

rdb文件放到redis安装目录启动redis即可加载,安装目录查询:redis-cli 输入config get dir。

APPEND ONLY MODE(aof)

appendonly no 是否开启aof持久化,如果rdb和aof同时开启则优先使用aof。

appendfilename "appendonly.aof" 设置aof文件的文件名。(默认"appendonly.aof")

appenddirname "appendonlydir" 设置aof文件的目录。

(从redis7版本开始,使用一组aof文件记录数据,分为两种基本类型:1、基本文件,表示文件创建时的完整的数据,可以是rdb或aof内容格式。2、增量文件,记录前一个文件之后的新增命令。另外,还有一个清单文件追踪文件的创建和使用顺序。文件名是以appendfilename前缀,后面跟着序号和类型。aof文件目录里生成的文件大概有:基本文件appendonly.aof.1.base.rdb、增量文件appendonly.aof.1.incr.aof,appendonly.aof.2.incr.aof......、清单文件appendonly.aof.manifest)

# appendfsync always 每次“写”操作都aof ,更安全。
appendfsync everysec 每秒aof,均衡。(默认)
# appendfsync no 不自动同步,由系统决定,更快。

no-appendfsync-on-rewrite no 使用always或者everysec时,可能会有阻塞发生,设置为yes时,如果后台有别的redis操作,会使用类似appendfsync no的机制(最差情况可能会丢失30s的数据),如果有延迟问题可以设置为“yes”,但设置为“no”将是最优选择。

auto-aof-rewrite-percentage 100 设置重写百分比,如果日志增长达到该百分比就会重写,redis会记住最后一次重写大小(如果重启时没有重写,则使用启动时的aof大小),设置为0禁用重写。(设置重写aof文件的最小大小,可以防止aof文件过小频繁重写问题)
auto-aof-rewrite-min-size 64mb 重写aof文件的最小大小。

aof-load-truncated yes 启动redis时对于损坏的aof文件的处理(系统崩溃可能导致aof文件结尾部分异常,但redis崩溃或终止不会损坏aof),设置为yes,启动时丢弃aof末尾的损坏数据并加载,同时通知给用户,设置为no,启动时发现aof损坏启动失败,需要先redis-check-aof --fix appendonly.aof修复才能启动redis。(注:如果aof文件中间损坏则启动redis异常)

aof-use-rdb-preamble yes 混合持久化,前部分是rdb格式,后部分是aof格式,结合两个持久化优点,只是可读性差,redis4.0版本之前不支持。可以为了向后兼容禁用。

aof-timestamp-enabled no 支持在aof中记录时间戳,可以在特定时间恢复数据,但会改变aof格式,可能跟已经存在的aof文件不兼容。

关于aof文件损坏:

  • 服务器正在写aof时宕机,或者写aof时磁盘满了,会导致最后的命令被截断,新版redis会加载有错误的aof,并丢弃文件最后一个错误的命令;
  • 对于旧版本redis可以使用:redis-check-aof --fix <filename> 命令修复aof文件,然后重新启动加载aof;
  • 如果aof文件中间出现错误,服务启动会报错,可以使用命令修复,但最好手动找到错误位置修改错误(因为aof也使用redis协议格式,修改很简单),自动修复命令可能会丢弃错误位置到aof结尾位置的全部内容,将丢失大部分数据;

关于rdb和aof切换:

redis2.2版本之后比较简单,例如rdb切到aof,只需将rdb文件保存备份,然后命令开启aof:redis-cli config set appendonly yes,可选关闭rdb:redis-cli config set save "";但这只是在命令里修改配置,还需将redis.conf文件的配置也一并修改了,否则下次重启又会失效;

备份数据:

备份rdb文件只需拷贝到安全的地方,服务器运行时赋值rdb很安全,因为rdb文件一旦创建就不会修改了,新的rdb文件产生时会用新文件,并在完成时重命名覆盖旧文件;

备份aof在redis7.0.0之前也可直接拷贝,但7.0.0版本之后会在aof文件夹下有多个文件,在aof重写时备份拷贝可能会得到无法使用的文件,所以在备份时需要关闭aof重写,步骤:

  1. 关闭自动aof重写,设置 CONFIG SET auto-aof-rewrite-percentage 0,并确保在此期间没有手动 BGREWRITEAOF 启动重写;
  2. 检查是否正在重写,查询 INFO persistence,如果返回1,则要等待重写完成;(并确认aof_rewrite_in_progress的确设置为0了)
  3. 将aof文件夹拷贝到安全地方;
  4. 重新打开自动aof重写 CONFIG SET auto-aof-rewrite-percentage <prev-value>;

参考:Redis persistence | Redis