Redis 两种持久化方式 AOF 和 RDB

目录

一、Redis 的持久化

二、Redis 的持久化方式

RDB

RDB 介绍

RDB 的触发方式:.

三、RDB的文件生成策略

四、Save 和 Bgsave 命令的区别

六、RDB 最佳配置

七、触发机制-不容忽略方式

AOF

一、AOF介绍

二、RDB所存在的问题

三、AOF 三种策略

四、AOF 重写实现原理

五、AOF 重写的两种方式

七、AOF 优缺点

1. 优点

2. 缺点

3、RDB 和 AOF 的选择

1. 数据格式:

2. 恢复速度:

3. 数据丢失:

4. 文件大小:

5. 随机访问性:

6. 系统稳定性:

7. 使用场景:

总结:

4、RDB 和 AOF 的选择


一、Redis 的持久化

redis 所有的数据都是保存在内存中,当 redis 进程挂了或者机器出现宕机等异常情况,如果不讲数据保存在硬盘中,那么数据将会丢失。redis 就提供了持久化的功能,就是可以将所有的数据修改也会异步更新在磁盘上。

二、Redis 的持久化方式

Redis 提供了两种持久化的方式:

  • RDB:这是一种快照的方式,它将 Redis 某时间点的数据都进行快照存储。比如 Mysql Dump 也是这种方式。
  • AOF:写日志的方式,记录每次对服务器写的操作, 当服务器重启的时候会重新执行这些命令来恢复原始的数据。例如 Mysql binlog,Hbase HLog。

RDB

RDB 介绍

在 Redis 运行时, RDB 将当前内存中的数据库生成一个 Snapshot 快照保存到磁盘文件中, 在 Redis 重启动时, RDB 可以通过载入 RDB 文件来还原数据库的状态。

Redis 两种持久化方式 AOF 和 RDB_第1张图片

RDB 的触发方式:.

RDB 有三种触发方式,其实就是生成 RDB 文件的方式。

save 命令:这个是同步方式,会阻塞当前其他的命令执行,直到save命令执行完毕。

bgsave 命令:这个是一个异步命令,会单独在后台去执行,不会阻塞其他命令。它其实是新创建(fork)了一个子进程,这个进程就是负责生成RDB文件的工作。

自动方式:就是在某些条件下会自动去生成,这个是在Redis配置文件中去设置。

Redis 两种持久化方式 AOF 和 RDB_第2张图片

这里说一下上面配置时间策略具体的意思。

  • 900 秒内有一个 key 变化
  • 300 秒内 10 个 key 变化
  • 60 秒内有 10000 个 key 发生变化。

三、RDB的文件生成策略

如果存在老的 RDB 文件,那么会生成一个临时文件,然后新生成的文件就会替换老的 RDB 文件。

四、Save 和 Bgsave 命令的区别

SAVE 和 BGSAVE 是两个用于执行 RDB 持久化的 Redis 命令,它们的主要区别在于执行方式的阻塞性和同步性:

SAVE:
SAVE 命令是一个阻塞式命令,它会阻塞 Redis 服务器的主线程,直到 RDB 快照完成为止。
在执行 SAVE 的过程中,Redis 服务器不能处理其他客户端的请求,因为它被阻塞在生成 RDB 快照的过程中。
由于阻塞性,SAVE 命令一般在非常小的数据集上使用,以避免对整个系统的性能造成显著影响。

127.0.0.1:6379> SAVE
OK

BGSAVE:
BGSAVE 命令是一个非阻塞式命令,它会在后台启动一个子进程来执行 RDB 快照,而不会阻塞主线程。
由于 BGSAVE 是非阻塞的,Redis 服务器可以继续处理其他命令和请求。
BGSAVE 命令是更常用的方式,特别是在生产环境中,因为它不会阻塞整个 Redis 服务。 

127.0.0.1:6379> BGSAVE
Background saving started

总体而言,大多数情况下,推荐使用 BGSAVE 而不是 SAVE,以避免对 Redis 服务器的性能产生负面影响。如果你需要确保在 BGSAVE 进程尚未完成时生成 RDB 文件,可以使用 SAVE 命令,但请注意这可能会导致系统暂时无法响应。

五、RDB 的持久化配置选项

# 时间策略
save 900 1
save 300 10
save 60 10000

# RDB文件名称
dbfilename dump.rdb

# 文件保存路径
dir /home/work/app/redis/data/

# 如果持久化出错,主进程是否停止写入
stop-writes-on-bgsave-error yes

# 是否压缩
rdbcompression yes

# 导入时是否检查
rdbchecksum yes

六、RDB 最佳配置

这里 RDB 最佳配置也是相对而言,具体也可以根据线上环境和具体业务来调整。这里只是一般通常配置

# RDB文件名称加上端口号进行文件的区别,现在机器多核,会运行多个Redis实例可以充分利用多核优势,这样产生多个RDB文件进行区分   dbfilename dump-${port}.rdb
# 文件保存路径
  dir /空间大的路径
# 如果持久化出错,主进程是否停止写入,这里选择开启,如果bgsave发生错误就不能正常的写入,说明redis就可能会出现问题了,这时候应该停止写入
stop-writes-on-bgsave-error yes
# 是否压缩,采用压缩,这样文件会比较小,而且Redis主从复制之间会有拷贝
rdbcompression yes

七、触发机制-不容忽略方式

  1. 全量复制:有时候没有执行 save,bgsave 命令或者配置文件设置 RDB 自动生成方式时候也会生成RDB文件,那是因为可能主从之间会有全量复制导致生成的,主节点会自动生成 RDB 文件。
  2. debug reload:进行 debug 级别的重启,不会将 Redis 内存进行清空的重启,这个时候也会触发 RDB 文件的生成。
  3. shutdown save:这个也会导致 RDB 文件的生成。

AOF

一、AOF介绍

Redis 的另一种持久化方式就是 AOF(Append Only File),与 RDB 持久化通过保存数据库中的键值对来记录数据库状态不同,AOF 是通过保存Redis所执行的写命令来记录数据库状态的。在了解 AOF 之前先看看 RDB 所存在的问题。

二、RDB所存在的问题

耗时,耗性能,每次保存 RDB 的时候Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时 fork() 可能会非常耗时,比如写的数据量很大,内存页设置的比较大,会产生很大的内存消耗,造成服务器在某某毫秒内停止处理客户端, 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至会更长。同时 RDB 也是一个 IO 的过程,RDB 文件很大拷贝速度就会很慢。Redis 两种持久化方式 AOF 和 RDB_第3张图片

不可控,容易丢失数据,服务器在发生故障时候会丢失数据。

下面是一个时间线流程操作说明

Redis 两种持久化方式 AOF 和 RDB_第4张图片

T3 和 T4 时间段所操作的命令都会丢失。因为无法知道什么时候会宕机及其他异常情况。如果使用 save 和 bgsave 做定时备份也是无法保障数据不会丢失。

如果避免 RDB 所出现的问题,这里就需要 AOF。

AOF 运行工作图

Redis 两种持久化方式 AOF 和 RDB_第5张图片

 客户端每执行一条命令都会被记录在 AOF 文件中。当 Redis 服务器宕机后,Redis 可以从 AOF 文件中恢复数据。

三、AOF 三种策略

Redis 提供了三种决定 AOF 写入的频率。

Redis 在执行写入 AOF 日志文件的时候不是直接去写入文件中,而是先记录在硬盘的缓冲区,缓冲区会根据一些刷新策略来决定什么时候刷新到磁盘中,这样会提高写入的效率。

1. always: 每次写入一条数据就立即将这个数据对应的写日志 fsync 到磁盘上去,虽然可以确保 Redis 里的数据一条都不丢,但是性能非常差,吞吐量很低。Redis 两种持久化方式 AOF 和 RDB_第6张图片

2. everysec:每秒将缓冲中的数据 fsync 到磁盘,这个比较最常用的,生产环境一般都这么配置,而且性能很高。但是缺点就是不像 always 那样保证每个命令都会记录,Redis 服务器出现故障有可能会丢失一秒钟的数据。 

3. no: 仅仅 redis 负责将数据写入缓冲区,什么时候刷新到磁盘中是根据操作系统自己决定。这种一般不会使用。 

四、AOF 重写实现原理

AOF 策略保证 Redis 命令写入到 AOF 文件中,不过随着命令逐步的写入,时间的推移,并发量写入量逐步的变大,AOF 文件的体积也会逐渐的变大。这时候使用 AOF 进行恢复数据会变的很慢。当 AOF 文件无限制的变大,无论是对于文件的管理,写入命令的速度都会有一定的影响。所以 Redis 提供了一个 AOF 重写的机制来解决这些问题。

Redis 两种持久化方式 AOF 和 RDB_第7张图片

根据上图分析原生 AOF 那一列最上面写入三条命令,都是对同一个 key 进行操作的,最后一次将前面两次写入的值更新了,实际上只有最后一次修改对我们是有用的。中间的 incr 自增命令也是一样的。下面三次 rpush 也是可以优化的,可以统一成一个命令。同时对于一些过期的数据,当时写入到 AOF 文件中,但是某个时间点已经过期了,这个 key 内部会执行一个删除命令操作并同步到 AOF 文件中,这个在 AOF 重写中是没有用的。

所以可以得出 AOF重写的作用

将过期的,没有用的,重复的命令,以及一些可以优化的命令都进行一个精简,来缩小 AOF 文件的体积,减少对磁盘的占用量。同时文件体积缩小也可以加速Redis恢复的速度。

五、AOF 重写的两种方式

1. 手动触发(Bgrewriteaof命令):这个命令有点类似于RDB中的bgsave,Bgrewriteaof 命令会fork一个子进程用于异步执行一个 AOF(AppendOnly File) 文件重写操作,重写会创建一个当前 AOF 文件的体积优化版本。即使 Bgrewriteaof 执行失败,也不会有任何数据丢失,因为旧的 AOF 文件在 Bgrewriteaof 成功之前不会被修改。

注意:从 Redis 2.4 开始, AOF 重写由 Redis 自行触发, BGREWRITEAOF 仅仅用于手动触发重写操作。Redis 两种持久化方式 AOF 和 RDB_第8张图片

自动触发:

自动触发与 AOF 重写配置几个参数有关。

  • auto-aof-rewrite-min-size:AOF 文件重写需要的最小的大小。就是说当 AOF 文件至少多大体积的时候在开始进行重写,默认 64M。
  • auto-aof-rewrite-percentage:AOF 文件增长率。当进行过了一次重写,下一次进行重写的时候看这个 AOF 文件的增长率,默认 100。
  • aof_current_size:当前 AOF 文件的大小(单位:字节)。
  • aof_base_size:上一次操作或者重写后的 AOF 文件大小(单位:字节)。

触发条件:

aof_current_size > auto-aof-rewrite-min-size 并且 (aof_current_size - aof_base_size) / aof_base_size >= auto-aof-rewrite-percentage。其中,aof_current_size 是当前 AOF 文件大小,aof_base_size 是上一次重写后 AOF 文件的大小,这两部分的信息可从 info Persistence 处获取。

AOF 重写流程图

Redis 两种持久化方式 AOF 和 RDB_第9张图片

六、AOF 配置项

# 打开AOF持久化机制,默认是no
appendonly yes
# AOF文件名
appendfilename appendonly-${port}.aof
# AOF同步策略appendfsync everysec 
# 文件保存路径
  dir /空间大的路径
#在AOF重写时候是否做正常的AOF的append操作,如果该参数设置为no,是最安全的方式,不会丢失数据,但是要忍受阻塞的问题。如果设置为yes呢?这就相当于将appendfsync设置为no,这说明并没有执行磁盘操作,只是写入了缓冲区,因此这样并不会造# 成阻塞(因为没有竞争磁盘),但是如果这个时候redis挂掉,就会丢失数据。丢失多少数据呢?在linux的操作系统的默认设置下,最多会丢失30s的数据。no-appendfsync-on-rewrite yes

七、AOF 优缺点

1. 优点

  • AOF 机制可以带来更高的数据安全性。
  • 由于该机制对日志文件的写入操作采用的是 append 模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容
  • AOF 包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。

2. 缺点

  • 对于相同数量的数据集而言,AOF 文件通常要大于 RDB 文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
  • AOF 对系统开销有一定的影响。AOF 常用的持久化策略是 everysec,在这种策略下,fsync 同步文件操作由专门线程每秒调用一次。当系统磁盘较忙时,会造成 Redis 主线程阻塞,所以在 Redis 的负载较高情况下,RDB 比 AOF 具好更好的性能保证。

3、RDB 和 AOF 的选择

RDB 和 AOF 对比

RDB(Redis DataBase)和 AOF(Append Only File)是两种不同的持久化机制,它们各自有一些优势和劣势。下面是它们之间的一些对比:

1. 数据格式:

  • RDB: 生成的是二进制的快照文件,包含了 Redis 在某个时间点上的所有数据。这种格式非常紧凑,适合用于备份和恢复。

  • AOF: 以文本格式追加写操作的日志文件,记录了每个写命令。这使得 AOF 文件相对容易阅读和人工修复。

2. 恢复速度:

  • RDB: 恢复速度一般比 AOF 快,因为它是一个完整的数据快照,只需读取 RDB 文件并加载到内存中即可。

  • AOF: 恢复速度可能比较慢,特别是对于大型 AOF 文件,因为需要逐行执行写操作来还原数据。

3. 数据丢失:

  • RDB: 在两次 RDB 文件生成之间的写操作可能会丢失,因为 RDB 是定期生成的。

  • AOF: 数据丢失的程度通常比较小,因为 AOF 记录了每个写操作。在发生故障时,只有最后一次写操作之后的数据可能会丢失。

4. 文件大小:

  • RDB: 通常比较小,因为它是一个完整的数据快照。

  • AOF: 可能比较大,特别是对于频繁写入的系统,因为它记录了每个写命令。

5. 随机访问性:

  • RDB: 适合大规模数据集的恢复,因为它是一个二进制文件,支持快速的随机访问。

  • AOF: 由于是文本文件,随机访问性相对较差。

6. 系统稳定性:

  • RDB: 在生成 RDB 文件期间会有一段时间的阻塞,因为 Redis 在生成 RDB 文件时执行 fork 操作。在这个时间段内,不能执行写操作。

  • AOF: AOF 在追加写操作时是非阻塞的,因此不会影响系统的响应性。

7. 使用场景:

  • RDB: 适合用于备份和定期快照,对于大型数据集的快速恢复。

  • AOF: 适合对数据的持久化要求更高,能够容忍一些性能开销,以及需要更精细的数据恢复场景。

总结:

  • 通常情况下,可以同时使用 RDB 和 AOF,以兼顾数据恢复的速度和可靠性。
  • 如果需要在故障时最小化数据丢失,并且对于恢复速度有较高的要求,可以使用 AOF 持久化。
  • 如果对于备份和快速恢复有较高要求,可以使用 RDB 持久化。

4、RDB 和 AOF 的选择

如果可以忍受一小段时间内数据的丢失,毫无疑问使用 RDB 是最好的,定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快,而且使用 RDB 还可以避免 AOF 一些隐藏的 bug;否则就使用 AOF 重写。但是一般情况下建议不要单独使用某一种持久化机制,而是应该两种一起用,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。Redis后期官方可能都有将两种持久化方式整合为一种持久化模型。

你可能感兴趣的:(Redis,redis,数据库,缓存)