Redis 中的持久化机制:RDB 与 AOF
文章目录
- Redis 中的持久化机制:RDB 与 AOF
- RDB
- 自动触发 RDB
- 手动触发 RDB
- RDB 缺点
- 禁用 RDB
- AOF
- 开启 AOF
- AOF 相关策略
- AOF 文件重写
Redis 中的持久化机制:RDB 与 AOF
Redis 提供 RDB 与 AOF 两种持久化机制。RDB 与 AOF 拥有各自优缺点,如果对数据安全性要求较高,则在实际开发中往往会结合两种机制来使用。
RDB | AOF | |
---|---|---|
持久化方式 | 定时对整个内存做快照 | 记录每一次执行的命令 |
数据完整性 | 不完整(两次备份之间会丢失) | 相对完整(取决于刷盘策略) |
文件大小 | 压缩则文件体积小 | 文件体积很大 |
宕机恢复速度 | 很快 | 慢 |
数据恢复优先级 | 低(数据完整性不高) | 高(数据完整性高) |
系统资源占用 | 高(大量 CPU 与内存消耗) | 通常低(主要占用磁盘 IO 资源)但重写时高 |
RDB 更适合对数据完整性要求较低,而对宕机恢复速度要求较高的场景;AOF 更适合对数据完整性要求高,但对宕机速度要求较低的场景。
RDB
RDB 全称 Redis Database Backup file(Redis 数据备份文件),也称 Redis 数据快照。简单来说就是将内存中的所有数据记录到磁盘中。当 Redis 实例故障重启后,从磁盘读取快照文件以达到恢复 Redis 数据目的。
RDB 默认是开启的。RDB 是 Redis 默认的数据持久化方式,将数据库的快照保存在 dump.rdb
(默认) 二进制文件中,快照文件称为 RDB 文件,默认保存在 Redis 当前运行目录。
自动触发 RDB
当主动对 Redis 进行停机时,Redis 会自动触发一次 RDB。此时 Redis 日志将输出:
Saving the final RDB snapshot before exiting.
DB saved on disk
Removing the pid file.
Redis is now ready to exit, bye bye...
手动触发 RDB
除了 Redis 宕机时自动触发 RDB,还可以使用 save
或 bgsave
命令以手动触发 RDB。
-
save
:由 Redis 主进程执行 RDB,由于 Redis 单线程原因,所以执行后将会阻塞主进程中所有 Redis 命令; -
bgsave
:开启子进程执行 RDB,执行后几乎不会阻塞主进程执行 Redis 命令,但是由于子进程是通过 fork 主进程而来的,所以还是会影响到主进程(在 fork 的过程中,主进程只能进行 fork 一项任务)。Redis 将数据写入物理内存的过程,并不是直接写入,而是通过写入 Linux 分配的虚拟内存间接写入物理内存。虚拟内存与物理内存的映射关系通过页码来维护,Linux 得到页码后将通过页码中维护的映射关系,将 Redis 数据写入物理内存。而子进程 fork 主进程的本质,实际上是对 Linux 操作系统页码的复制,子进程获取到主进程的页码后,就可以通过页码定位物理内存数据,从而异步写入磁盘中。
为了避免主进程向内存中写数据,同时子进程在内存中读数据的情况发生,fork 采用 copy-on-write 技术。copy-on-write 技术会在主进程执行读操作时,访问主进程与子进程共享的内存数据;而在主进程进行写操作时,则会将共享的内存数据标记为 read-only 之后,拷贝一份内存数据,专门用于提供给主进程进行写操作。
也可以通过配置 Redis 配置文件的 save [时间(秒)] [变化KEY的数量]
项达到让 Redis 自动触发 RDB 的目的(默认 save 900 1
)。例如:
# RDB的bgsava操作。默认900秒(十五分钟)内有1个key发生变化则执行。
save 900 1
除了在 Redis 配置文件中配置 RDB 的自动触发,还可以配置其他 RDB 相关配置:
# RDB文件是否压缩:默认开启,建议关闭(关闭的是目的是牺牲磁盘空间以节省CPU消耗)
rdbcompression yes
# RDB文件名:默认dump.rdb
dbfilename dump.rdb
# RDB文件保存路径:默认./
dir ./
RDB 缺点
RDB 机制存在两个缺点:
- RDB 间隔时间长,两次 RDB 之间存在数据丢失风险;
- fork 子进程、压缩、写入 RDB 文件都比较耗时。
禁用 RDB
通过修改配置禁用 RDB:
# RDB禁用
save ""
AOF
AOF 全称为 Append Only File(追加文件)。开启 AOF 后(默认未开启),Redis 处理的每一个写命令都会记录到 AOF 文件中。
开启 AOF
可以通过修改 Redis 配置文件开启 AOF:
# AOF持久化功能开关:默认no,即不开启。
appendonly yes
# AOF持久化文件名,默认文件名为appendonly.aof
appendfilename "appendonly.aof"
# AOF策略:值可以为always、everysec或no;
# 值为always:表示每执行一次写命令,立刻记录到AOF日志文件;
# 值为everysec:表示写命令执行完先放入AOF缓冲区,然后每隔1秒将缓存区数据写入AOF文件中(默认)
# 值为no:表示写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写入AOF文件。
appendfsync always
# AOF持久化文件保存路径,与RDB持久化文件保持一致即可
dir=""
AOF 相关策略
配置项 | 刷盘时机 | 优点 | 缺点 |
---|---|---|---|
always | 同步刷盘 | 可靠性高,几乎不丢失数据 | 性能影响大 |
everysec(推荐) | 每秒刷盘 | 性能适中 | 最多丢失一秒数据 |
no | 操作系统控制 | 性能最好 | 可靠性差,可能丢失大量数据 |
AOF 文件重写
在默认情况下,AOF 文件要比 RDB 文件大很多,根本原因在于 AOF 记录的是操作命令,而 RDB 记录的是操作数据。但是如果对同一个 Key 进行多次操作,并通过 AOF 进行记录是没有意义的,因为只有最后一次写操作才有意义。通过执行 bgrewriteaof
命令可以让 Redis 重写 AOF 文件,从而避免上述问题。
bgrewriteaof
命令可以被手动触发,从而立刻重写 aof 文件。执行正常的情况下将输出结果:
Background append only file rewriting started
此时,重写 AOF 文件的动作将会在后台被执行。
bgrewriteaof
命令也可以通过配置 Redis 配置文件的方式自动触发:
# 触发AOF重写所需要的aof文件体积百分比,aof文件增量大于100%(即一倍)才进行重写,0为关闭AOF自动重写
auto-aof-rewrite-percentage 100
# 触发AOF重写的最小文件体积,大于或等于64MB自动触发
auto-aof-rewrite-min-size 64mb