Redis
的数据是存储在内存当中, 因为服务器宕机、停电等情况,Redis
中的数据容易丢失。这时Redis
持久化的作用就体现出来了。例: 可以用来完成数据恢复、故障恢复数据等。
Redis
持久化分为三种策略机制:RDB(Redis DataBase)
、AOF(Append Only File)
、两种方式混合持久化。
本文简要的描述两种方式。 如需深层次的知识点, 恭请各位大佬进入高级区查阅。
点我查看 - Redis 订阅与 Redis Stream 技术
RDB
是指周期性的将内存中的数据集快照写入磁盘文件。
这种方式是也就是将内存中的数据以快照的方式写入二进制文件中, 默认的文件名为
dump.rdb
, 在Redis
重启时, 通过加载dump.rdb
文件来恢复数据。
顾名思义, 自动触发是
Redis
在某个时间内, 自动执行持久化操作, 将数据进行备份。
Redis
配置文件是/usr/local/redis/bin/redis.conf
。
这是我的
redis.conf
所在位置, 根据自己情况找到该文件打开后, 我的在 412 行开始是快照的配置
我这里默认
RDB
持久化功能是关闭的,# save ""
, 我的在 424 行
dbfilename dump.rdb
文件名配置, 我的在 481 行
dir ./
备份文件保存目录配置, 我的在 504 行默认都是注释着的, 如果要启用, 将行开头的
#
去掉
# 配置格式: save m n [m n ...]
# 解释: 在 m 秒内, 如果有 n 个键发生改变, 则自动触发持久化操作, 可配置多个条件
# 例: save 3600 1 300 100 60 10000
# 例解: 3600 秒内, 如果有 1 个键发生改变, 则自动触发持久化操作
# 例解: 300 秒内, 如果有 100 个键发生改变, 则自动触发持久化操作
# 例解: 60 秒内, 如果有 10000 个键发生改变, 则自动触发持久化操作
顾名思义, 手动触发就是通过 手动执行命令 来完成持久化操作。
手动触发的命令有两个:
save()
、bgsave()
, 他们之间的主要区别在于是否会阻塞线程。
SAVE 命令:
save()
命令触发Redis
同步持久化。- 缺点: 会使
Redis
处于阻塞状态, 不能执行其他命令, 直到RDB
持久化完成。- 优点: 虽然不会消耗额外的内存,但生产环境慎用。
BGSAVE 命令:
bgsave()
会执行fork
操作创建子进程, 持久化的工作由子进程完成, 整个过程只有在fork
子进程的时候有短暂的阻塞, 当子进程被创建后, 就可以响应其他客户端的请求了。
bgsave()
命令触发Redis
异步持久化。- 缺点: 创建子进程, 需要消耗更多内存。
- 优点: 创建子进程后, 其他客户端还可以交互, 大多数情况采用
bgsave()
。
RDB
的持久化文件为二进制数据, 占用内存更小。RDB
因为备份的是数据库的快照, 所以非常适合冷备份, 比如 凌晨1点的时候, 进行持久化操作。- 在面对大数据的情况下,
RDB
备份与恢复速度比AOF
快。
RDB
是周期性进行备份, 如果发生意外情况, 且这段时间有数据交互, 就会丢失这段时间的数据。- 无法实现 实时持久化。
- 因为是全量备份, 且还经常创建子进程, 数据量大的话, 会长期消耗服务器CPU与内存。
AOF
采用日志方式记录, 将执行完的命令、命令参数、参数个数等信息通过write
函数追加到日志文件末尾。
命令同步流程:
- 将命令或参数等发送至
AOF
程序AOF
程序收到后, 因为Redis
是单线程, 通过resp
协议, 将数据暂存到AOF
缓冲区- 通过设置的同步策略, 将暂存区的命令同步追加到文件末尾
# 同步策略由 appendfsync 参数决定, 我的在 1435 行开始
# appendfsync always
appendfsync everysec # 默认
# appendfsync no
always
AOF
缓冲区收到数据时, 立即调用fsync
命令强制往AOF
文件写数据。everysec
AOF
缓冲区收到数据时, 调用write
命令往io
缓冲区写数据, 同时以每秒调用一次fsync
命令, 强制将io
缓冲区的数据写入AOF
文件。no
AOF
缓冲区收到数据时, 调用write
命令往io
缓冲区写数据, 当io
缓冲区填满时或系统定期的将io
缓冲区的数据写入AOF
文件。
随着执行命令越来越多,
AOF
文件会越来越大, 可采用 AOF 重写机制 解决这一问题。
重写会启用一个后台子进程
bgrewriteaof
。
AOF 重写 是去除
AOF
文件中 无效的命令、超时的数据 等或采用 命令合并 方式, 创建一个新的AOF
文件来保存重写后的命令。no-appendfsync-on-rewrite no # 重写机制默认是关闭的, 如需开启, 请改为 yes , 我的在 1460 行
手动触发
AOF
重写可以由用户通过调用BGREWRITEAOF
命令手动触发。自动触发
根据
auto-aof-rewrite-percentage
与auto-aof-rewrite-min-size 64mb
确定触发时机。# 我的在 1479 行 auto-aof-rewrite-percentage 100 # 当前 AOF 文件大小(aof_current_size) 比 之前重写后的大小(aof_base_size) 至少大了 100% auto-aof-rewrite-min-size 64mb # AOF 体积大于 64mb 会触发重写
默认
AOF
持久化功能是关闭的。
Redis
配置文件是/usr/local/redis/bin/redis.conf
。打开后, 我的在 1359 行是配置的开始。appendonly yes # 开启, 改为 yes , 我的在 1379 行 appendfilename "appendonly.aof" # 快照基本文件名 appenddirname "appendonlydir" # 存储专用目录
- 可以更好的保护数据完整性, 比
RDB
更靠谱- 即使文件过大, 也可以采用 重写 方式, 不影响客户端
- 因为同步策略, 一般情况下
AOF
的速度慢于RDB
- 即使一直在重写, 但文件体积还是要比
RDB
的二进制文件大AOF
在恢复时, 会重演每条命令, 速度也比RDB
慢- 因体量较大, 恢复时, 可能存在写坏, 可通过对比两文件差异, 使用
redis-check-aof --fix AOF文件名
修复,diff -u
来对比文件的差异, 进而确定后再恢复。
方式 | 存储速度 | 恢复速度 | 数据完整性 | 文件大小 | 资源消耗 |
---|---|---|---|---|---|
RDB | 慢 | 快 | 不可抗拒因素, 可能会丢失数据 | 小 | 高 |
AOF | 快 | 慢 | 依据同步策略,视情况而定, 可能会写坏 | 大 | 低 |
根据业务场景选择合适的持久化方式, 默认
RDB
。
- 如果业务场景主要充当缓存功能, 失效重新访问数据获取, 不怎么依赖持久化, 则选择
RDB
。- 如果数据需要持久保存, 确保数据的完整性, 则建议
RDB
与AOF
同时启用。
点我查看 - Redis 订阅与 Redis Stream 技术