Redis的数据是存储在内存当中, 因为服务器宕机、停电等情况,Redis中的数据容易丢失。这时Redis持久化的作用就体现出来了。例: 可以用来完成数据恢复、故障恢复数据等。
Redis持久化分为三种策略机制:RDB(Redis DataBase)、AOF(Append Only File)、两种方式混合持久化。
本文简要的描述两种方式。 如需深层次的知识点, 恭请各位大佬进入高级区查阅。
点我查看 - Redis 基本知识,快来回顾一下
点我查看 - Redis 订阅与 Redis Stream 技术
点我查看 - PHP 使用 PHPRedis 与 Predis
一、RDB(Redis DataBase)RDB是指周期性的将内存中的数据集快照写入磁盘文件。
这种方式是也就是将内存中的数据以快照的方式写入二进制文件中, 默认的文件名为dump.rdb, 在Redis重启时, 通过加载dump.rdb文件来恢复数据。
1.1 RDB 的触发方式 1.1.1 自动触发顾名思义, 自动触发是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 个键发生改变, 则自动触发持久化操作1.1.2 手动触发
顾名思义, 手动触发就是通过 手动执行命令 来完成持久化操作。
手动触发的命令有两个:save()、bgsave(), 他们之间的主要区别在于是否会阻塞线程。
SAVE 命令:
- save()命令触发Redis同步持久化。
- 缺点: 会使Redis处于阻塞状态, 不能执行其他命令, 直到RDB持久化完成。
- 优点: 虽然不会消耗额外的内存,但生产环境慎用。
BGSAVE 命令:
bgsave()会执行fork操作创建子进程, 持久化的工作由子进程完成, 整个过程只有在fork子进程的时候有短暂的阻塞, 当子进程被创建后, 就可以响应其他客户端的请求了。
- bgsave()命令触发Redis异步持久化。
- 缺点: 创建子进程, 需要消耗更多内存。
- 优点: 创建子进程后, 其他客户端还可以交互, 大多数情况采用bgsave()。
- RDB的持久化文件为二进制数据, 占用内存更小。
- RDB因为备份的是数据库的快照, 所以非常适合冷备份, 比如 凌晨1点的时候, 进行持久化操作。
- 在面对大数据的情况下,RDB备份与恢复速度比AOF快。
- RDB是周期性进行备份, 如果发生意外情况, 且这段时间有数据交互, 就会丢失这段时间的数据。
- 无法实现 实时持久化。
- 因为是全量备份, 且还经常创建子进程, 数据量大的话, 会长期消耗服务器CPU与内存。
AOF采用日志方式记录, 将执行完的命令、命令参数、参数个数等信息通过write函数追加到日志文件末尾。
2.1 同步流程命令同步流程:
- 将命令或参数等发送至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。
2.3.1 配置AOF 重写 是去除AOF文件中 无效的命令、超时的数据 等或采用 命令合并 方式, 创建一个新的AOF文件来保存重写后的命令。
no-appendfsync-on-rewrite no # 重写机制默认是关闭的, 如需开启, 请改为 yes , 我的在 1460 行2.3.2 触发重写
-
手动触发
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" # 存储专用目录2.5 AOF 的优缺点 2.5.1 AOF 的优点
- 可以更好的保护数据完整性, 比RDB更靠谱
- 即使文件过大, 也可以采用 重写 方式, 不影响客户端
- 因为同步策略, 一般情况下AOF的速度慢于RDB
- 即使一直在重写, 但文件体积还是要比RDB的二进制文件大
- AOF在恢复时, 会重演每条命令, 速度也比RDB慢
- 因体量较大, 恢复时, 可能存在写坏, 可通过对比两文件差异, 使用redis-check-aof --fix AOF文件名修复,diff -u来对比文件的差异, 进而确定后再恢复。
根据业务场景选择合适的持久化方式, 默认RDB。
- 如果业务场景主要充当缓存功能, 失效重新访问数据获取, 不怎么依赖持久化, 则选择RDB。
- 如果数据需要持久保存, 确保数据的完整性, 则建议RDB与AOF同时启用。
点我查看 - Redis 基本知识,快来回顾一下
点我查看 - Redis 订阅与 Redis Stream 技术
点我查看 - PHP 使用 PHPRedis 与 Predis