一、Redis持久化概述
Redis的持久化是指将数据从内存中保存到磁盘上,以确保在Redis重启或崩溃时能够恢复数据。Redis支持两种主要的持久化方式:RDB(Redis Database)和AOF(Append Only File)。
Redis persistence 官网介绍https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/
二、RDB持久化
-
定义与原理
RDB持久化是通过生成某一时刻( point-in-time)的数据快照(Snapshot)的方式,将Redis内存中的数据写入到磁盘上的二进制文件中。这个文件被称为RDB文件(默认为dump.rdb),可以在Redis重启时用于恢复数据。在持久化时,Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,所以RDB方式要比AOF方式更加的高效。
-
触发机制
RDB持久化可以手动触发,也可以使用自动触发机制。
- 手动触发:使用
SAVE
或BGSAVE
命令。SAVE
命令会阻塞当前Redis服务器,直到RDB过程完成为止,一般不推荐使用。BGSAVE
命令会创建一个子进程来执行RDB持久化过程,不会阻塞主进程。 - 自动触发:在Redis配置文件中设置触发条件,如“save m n”表示m秒内数据集发生了n次修改,则自动触发RDB持久化。
-
执行flushall命令时,也会产生dump.rdb文件,但里面是空的,无意义。
- 手动触发:使用
-
配置与优化
- 在Redis配置文件中,可以通过修改
dir
属性来设置RDB文件的存储目录。 - 可以使用
rdbcompression
参数来控制RDB文件是否压缩,默认是开启的。 - 可以使用
rdbchecksum
参数来开启RDB文件的校验功能,以确保文件的完整性。 -
stop-writes-on-bgsave-error 当Redis无法写入磁盘的话,直接关掉Redis的写操作推荐yes。
- 禁用RDB缓存,不设置save指令,或者给save传入空字符串
- 在Redis配置文件中,可以通过修改
-
恢复数据
当Redis重启时,会自动加载RDB文件中的数据来恢复内存状态。
-
优缺点
-
优点:
- 只有一个紧凑的二进制文件,非常适合备份和全量复制的场景。
- 容灾性好,RDB文件可以拷贝到远程机器或文件系统中进行容灾恢复。
- 恢复速度快,RDB恢复数据的速度远远快于AOF方式。
- 使用单独子进程进行持久化,主进程不进行任何IO操作,保证了Redis的高性能。
- 缺点:
- 实时性低,RDB是间隔一段时间进行持久化,无法做到实时持久化或秒级持久化。如果在这一间隔内发生故障,数据会丢失。
- 存在兼容问题,Redis演进过程中存在多个格式的RDB版本,老版本Redis可能无法兼容新版本RDB文件。
- Fork时内存中的数据被克隆了一份,大致两倍的膨胀量需要考虑,数据量庞大时消耗性能。
三、AOF持久化
-
定义与原理
AOF持久化是通过记录每次写操作的日志来实现数据的持久化。Redis将每次写操作(如SET、INCR等)增量的记录到AOF文件中,当Redis重启时,可以通过重放AOF文件中的写操作来恢复数据。
-
AOF持久化流程
客户端的请求写命令会被append追加到AOF缓冲区内;
AOF缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件
AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量
Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;
-
开启与配置
- 在Redis配置文件中,将
appendonly
属性设置为yes
来开启AOF持久化,AOF文件的保存路径,同RDB的路径一致。 - 可以使用
appendfilename
属性来设置AOF文件的名称。 - 可以使用
appendfsync
属性来设置AOF文件的同步策略,包括always
(每次写操作都同步)、everysec
(每秒同步一次)和no
(由操作系统决定何时同步)三种模式。
- 在Redis配置文件中,将
-
重写机制
- 什么是重写机制 AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制, 当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩, 只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof
-
重写原理,如何实现重写
AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),redis4.0版本后的重写,是指上就是把rdb 的快照,以二级制的形式附在新的aof头部,作为已有的历史数据,替换掉原来的流水账操作。
no-appendfsync-on-rewrite:
如果 no-appendfsync-on-rewrite=yes ,不写入aof文件只写入缓存,用户请求不会阻塞,但是在这段时间如果宕机会丢失这段时间的缓存数据。(降低数据安全性,提高性能)
如果 no-appendfsync-on-rewrite=no, 还是会把数据往磁盘里刷,但是遇到重写操作,可能会发生阻塞。(数据安全,但是性能降低)
触发机制,何时重写
Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
重写虽然可以节约大量磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis要满足一定条件才会进行重写。
auto-aof-rewrite-percentage:设置重写的基准值,文件达到100%时开始重写(文件是原来重写后文件的2倍时触发)
auto-aof-rewrite-min-size:设置重写的基准值,最小文件64MB。达到这个值开始重写。
例如:文件达到70MB开始重写,降到50MB,下次什么时候开始重写?100MB
系统载入时或者上次重写完毕时,Redis会记录此时AOF大小,设为base_size,
如果Redis的AOF当前大小>= base_size +base_size*100% (默认)且当前大小>=64mb(默认)的情况下,Redis会对AOF进行重写。
-
重写流程
(1)bgrewriteaof触发重写,判断是否当前有bgsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行。
(2)主进程fork出子进程执行重写操作,保证主进程不会阻塞。
(3)子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失。
(4)子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。主进程把aof_rewrite_buf中的数据写入到新的AOF文件。
(5)使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。
。
-
恢复数据
- 当Redis重启时,会首先尝试加载AOF文件中的数据来恢复内存状态。
- 如果AOF文件损坏,可以使用
redis-check-aof
工具来进行修复。
-
优缺点
优点:- 数据安全,AOF持久化可以配置appendfsync属性,确保数据完整性。
- 实时性好,AOF持久化可以配置为每次写入都同步到硬盘,减少数据丢失的风险。
- 通过append模式写文件,即使中途服务器宕机,可以通过redis-check-aof工具解决数据一致性问题。
缺点:
AOF文件比RDB文件大,且恢复速度慢; 数据集大的时候,比RDB启动效率低;AOF文件的重写过程需要消耗一定的资源。
四、RDB与AOF的混合使用
-
定义与原理
Redis 4.0及以上版本支持RDB和AOF的混合持久化。在这种模式下,Redis 会根据配置定时进行 RDB 快照保存,并在每次写操作后追加到 AOF 文件中。当 Redis 重启时,会优先使用 AOF 文件来恢复数据,因为 AOF 文件保存的数据集通常比 RDB 文件更完整。
-
配置与使用
- 在Redis配置文件中,将
aof-use-rdb-preamble
属性设置为yes
来开启混合持久化。 - 混合持久化结合了RDB和AOF的优点,既能够快速地恢复数据,又能够减少数据丢失的风险。
- 在Redis配置文件中,将
五、注意事项
- 在使用RDB持久化时,需要注意触发条件的设置,以避免频繁生成RDB文件对性能的影响。
- 在使用AOF持久化时,需要选择合适的同步策略来平衡性能和数据安全性。
- 定期检查和备份RDB和AOF文件,以确保数据的可靠性。
- 在使用混合持久化时,需要确保Redis版本支持该功能,并合理配置相关参数。
通过上述步骤和注意事项,可以有效地使用RDB和AOF方式来实现Redis数据的持久化。