官方文档:https://redis.io/docs/management/persistence/
Redis提供了主要提供了 2 种不同形式的持久化方式:
RDB(Redis数据库):RDB 持久性以指定的时间间隔执行数据集的时间点快照。
AOF(Append Only File):AOF 持久化记录服务器接收到的每个写操作,在服务器启动时再次播放,重建原始数据集。 命令使用与 Redis 协议本身相同的格式以仅附加方式记录。 当日志变得太大时,Redis 能够在后台重写日志(对日志进行瘦身)。
RDB 和 AOF 文件同时存在,Redis 默认使用的是 AOF 文件。
一、RDB
1、定义:
在指定的时间间隔内将内存中的数据集快照写入磁盘, 也就是Snapshot快照,它恢复时是将快照文件直接读到内存里。
2、备份
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束后,再用这个临时文件替换上次持久化好的文件。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
3、Fork
Fork 的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等) 数值都和原进程一致,但它是一个全新的进程,并作为原进程的子进程。
在 Linux 程序中,fork() 会产生一个和父进程完全相同的子进程,但子进程在此后多会 exec 系统调用,出于效率考虑,Linux 中引入了“写时复制技术”。
一般情况下父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。
4、持久化流程
启动:
-
检查是否存在子进程正在执行 AOF 或者 RDB 的持久化任务。如果有则返回 false。
-
调用 Redis 源码中的 rdbSaveBackground 方法,方法中执行 fork() 产生子进程执行 RDB 操作。
-
关于 fork() 中的 Copy-On-Write。
RDB的配置:
如何取消RDB的机制即禁用RDB:
save ""
# save 3600 1 300 100 60 10000 # 触发RDB的机制
stop-writes-on-bgsave-error yes # 如果RDB持久化的过程中发生了错误,停止写的操作
rdbcompression yes # 启动压缩
rdbchecksum yes # 校验文件完整性
dbfilename dump.rdb # 指定文件的名称
rdb-del-sync-files no # #默认配置是 rdb-del-sync-files no,主从进行全量同步时, 通过传输 RDB 内存快照文件实现,
# 没有开启 RDB 持久化的实例在同步完成后会删除该文件,通常情况下保持默认即可
dir ./ # 指定存储的目录
优势
RDB 方式适合大规模的数据恢复,并且对数据完整性和一致性要求不高更适合使用。它有以下几种优势:
-
节省磁盘空间
-
恢复速度快
劣势
-
Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
-
虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。
-
在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。
二、AOF
1、什么是AOF
以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录), 只追加文件但不可以改写文件,Redis启动之初会读取该文件重新构建数据。简单说,Redis 重启时会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
在Redis的默认配置中AOF(Append Only File)持久化机制是没有开启的,要想使用AOF持久化需要先开启此功能。AOF持久化会将被执行的写命令写到AOF文件末尾,以此来记录数据发生的变化,因此只要Redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复AOF文件的记录的数据集。
2、持久化流程
1)客户端的请求写命令会被 append 追加到 AOF 缓冲区内。
2)AOF 缓冲区根据 AOF 持久化策略 [always,everysec,no] 将操作sync同步到磁盘的 AOF 文件中。
3)AOF 文件大小超过重写策略或手动重写时,会对 AOF 文件 rewrite 重写,压缩 AOF 文件容量。
4)Redis 服务重启时,会重新 load 加载 AOF 文件中的写操作达到数据恢复的目的。
3、使用AOF
1、开启AOF
修改 redis.conf 配置文件:
-
通过修改redis.conf配置中
appendonly yes
来开启AOF持久化 -
通过appendfilename指定日志文件名字(默认为appendonly.aof)
-
通过appendfsync指定日志记录频率
2、配置选项
选项 | 同步频率 |
---|---|
always | 每个redis写命令都要同步写入硬盘,严重降低redis速度 |
everysec | 每秒执行一次同步显式的将多个写命令同步到磁盘 |
no | 由操作系统决定何时同步 |
相关配置
appendonly no # 是否开启AOF
appendfilename "appendonly.aof" # AOF文件的基名
# 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.
appenddirname "appendonlydir" # AOF存储的目录
appendfsync everysec # 刷盘的时机
every sec: 每秒刷一次
always: 总是:每一次写操作都刷盘
no:redis不决定刷盘的时机,交给操作系统
no-appendfsync-on-rewrite no # 在重写的时候是否进行刷盘
# 触发AOF重写的机制:
auto-aof-rewrite-percentage 100 # 100% 对比:上次文件大小
auto-aof-rewrite-min-size 64mb # 最小文件大小64mb
aof-load-truncated yes # 是否加载后清空aof
aof-use-rdb-preamble yes # rdb+aof的方式来持久化
aof-timestamp-enabled no # 是否启用时间戳
优势
- 备份机制更稳健,丢失数据概率更低。
- 可读的日志文本,通过操作AOF稳健,可以处理误操作。
劣势
- 比起RDB占用更多的磁盘空间。
- 恢复备份速度要慢。
- 每次读写都同步的话,有一定的性能压力。
- 存在个别Bug,造成恢复不能。
如果Redis的AOF当前大小>= base_size +base_size*100% (默认)且当前大小>=64mb(默认)的情况下,Redis会对AOF进行重写
# 自动触发AOF Rewrite的条件
auto-aof-rewrite-percentage 100%
auto-aof-rewrite-min-size 64MB