目录
一、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 文件来还原数据库的状态。
RDB 的触发方式:.
RDB 有三种触发方式,其实就是生成 RDB 文件的方式。
save 命令:这个是同步方式,会阻塞当前其他的命令执行,直到save命令执行完毕。
bgsave 命令:这个是一个异步命令,会单独在后台去执行,不会阻塞其他命令。它其实是新创建(fork)了一个子进程,这个进程就是负责生成RDB文件的工作。
自动方式:就是在某些条件下会自动去生成,这个是在Redis配置文件中去设置。
这里说一下上面配置时间策略具体的意思。
- 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
七、触发机制-不容忽略方式
- 全量复制:有时候没有执行 save,bgsave 命令或者配置文件设置 RDB 自动生成方式时候也会生成RDB文件,那是因为可能主从之间会有全量复制导致生成的,主节点会自动生成 RDB 文件。
- debug reload:进行 debug 级别的重启,不会将 Redis 内存进行清空的重启,这个时候也会触发 RDB 文件的生成。
- shutdown save:这个也会导致 RDB 文件的生成。
AOF
一、AOF介绍
Redis 的另一种持久化方式就是 AOF(Append Only File),与 RDB 持久化通过保存数据库中的键值对来记录数据库状态不同,AOF 是通过保存Redis所执行的写命令来记录数据库状态的。在了解 AOF 之前先看看 RDB 所存在的问题。
二、RDB所存在的问题
耗时,耗性能,每次保存 RDB 的时候Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时 fork() 可能会非常耗时,比如写的数据量很大,内存页设置的比较大,会产生很大的内存消耗,造成服务器在某某毫秒内停止处理客户端, 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至会更长。同时 RDB 也是一个 IO 的过程,RDB 文件很大拷贝速度就会很慢。
不可控,容易丢失数据,服务器在发生故障时候会丢失数据。
下面是一个时间线流程操作说明
T3 和 T4 时间段所操作的命令都会丢失。因为无法知道什么时候会宕机及其他异常情况。如果使用 save 和 bgsave 做定时备份也是无法保障数据不会丢失。
如果避免 RDB 所出现的问题,这里就需要 AOF。
AOF 运行工作图
客户端每执行一条命令都会被记录在 AOF 文件中。当 Redis 服务器宕机后,Redis 可以从 AOF 文件中恢复数据。
三、AOF 三种策略
Redis 提供了三种决定 AOF 写入的频率。
Redis 在执行写入 AOF 日志文件的时候不是直接去写入文件中,而是先记录在硬盘的缓冲区,缓冲区会根据一些刷新策略来决定什么时候刷新到磁盘中,这样会提高写入的效率。
1. always: 每次写入一条数据就立即将这个数据对应的写日志 fsync 到磁盘上去,虽然可以确保 Redis 里的数据一条都不丢,但是性能非常差,吞吐量很低。
2. everysec:每秒将缓冲中的数据 fsync 到磁盘,这个比较最常用的,生产环境一般都这么配置,而且性能很高。但是缺点就是不像 always 那样保证每个命令都会记录,Redis 服务器出现故障有可能会丢失一秒钟的数据。
3. no: 仅仅 redis 负责将数据写入缓冲区,什么时候刷新到磁盘中是根据操作系统自己决定。这种一般不会使用。
四、AOF 重写实现原理
AOF 策略保证 Redis 命令写入到 AOF 文件中,不过随着命令逐步的写入,时间的推移,并发量写入量逐步的变大,AOF 文件的体积也会逐渐的变大。这时候使用 AOF 进行恢复数据会变的很慢。当 AOF 文件无限制的变大,无论是对于文件的管理,写入命令的速度都会有一定的影响。所以 Redis 提供了一个 AOF 重写的机制来解决这些问题。
根据上图分析原生 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 仅仅用于手动触发重写操作。
自动触发:
自动触发与 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 重写流程图
六、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后期官方可能都有将两种持久化方式整合为一种持久化模型。