redis的备份和恢复
一.redis的备份机制
Redis 提供两种核心持久化方式,备份需基于这两种机制实现
1.RDB 备份(快照方式)
RDB 是 Redis 默认的持久化方式,通过生成内存数据的二进制快照文件(dump.rdb)实现备份,适合全量备份。
RDB 本质是 “内存数据的瞬时快照”,其工作流程分为 3 个关键步骤:
- 触发备份:通过手动命令(如
BGSAVE)或自动配置(如save 900 1)触发快照。 - 后台写入:
- Redis 会 fork 一个子进程(避免阻塞主线程),子进程负责遍历内存中的键值对,将数据写入临时文件。
- 主线程继续处理业务请求,期间新写入 / 修改的数据会通过 “写时复制(Copy-On-Write)” 机制保留在父进程内存,不影响子进程的快照生成。
- 替换文件:子进程写完临时文件后,会原子性替换旧的
dump.rdb文件(确保备份文件完整性,避免部分写入导致损坏)。
| 命令 | 特点 | 适用场景 |
|---|---|---|
SAVE | 主线程直接执行快照,期间阻塞所有业务请求(无法处理 GET/SET 等命令) | 测试环境、数据量极小的场景 |
BGSAVE | 后台异步执行(fork 子进程处理),主线程不阻塞 | 生产环境(数据量较大时优先) |
手工备份
# 后台异步生成 RDB 备份(生产环境常用)
redis-cli -a 密码 BGSAVE# 查看备份进度(通过 INFO persistence 检查)
redis-cli -a 密码 INFO persistence | grep "rdb_bgsave_in_progress"
# 输出 0 表示备份完成,1 表示正在备份# 假设 RDB 路径为 /var/lib/redis/dump.rdb
cp /var/lib/redis/dump.rdb /backup/redis/dump_$(date +%Y%m%d).rdb配置文件自动触发备份
在 redis.conf 中配置 “时间 + 修改次数” 的触发规则,Redis 会定期自动生成快照,无需手动干预:
# 规则格式:save <秒数> <修改次数> → 表示“N秒内至少M个键被修改,则触发快照”
save 900 1 # 900秒(15分钟)内至少1个键修改,触发备份
save 300 10 # 300秒(5分钟)内至少10个键修改,触发备份
save 60 10000 # 60秒内至少10000个键修改,触发备份RDB 备份文件的关键配置
redis.conf 中与 RDB 相关的核心配置,决定了备份文件的路径、名称和安全性:
| 配置项 | 作用 | 默认值 |
|---|---|---|
dbfilename | RDB 备份文件的名称 | dump.rdb |
dir | RDB 文件的存储路径(需确保 Redis 有读写权限) | /var/lib/redis(Linux) |
rdbcompression | 是否启用数据压缩(用 LZF 算法压缩,减少文件体积,轻微消耗 CPU) | yes(推荐开启) |
rdbchecksum | 是否对 RDB 文件做 CRC64 校验(确保文件未损坏,轻微增加备份时间) | yes(推荐开启) |
stop-writes-on-bgsave-error | 若 BGSAVE 失败,是否禁止后续写入(避免数据丢失,生产环境推荐开启) | yes |
配置示例
dbfilename "redis_backup.rdb" # 自定义备份文件名
dir "/data/redis/backup" # 备份文件存放在 /data/redis/backup
rdbcompression yes # 启用压缩
rdbchecksum yes # 启用校验2.AOF 备份(日志方式)
AOF(Append Only File)通过记录所有写命令(如 SET、HSET)实现持久化,适合需要更高数据安全性的场景(丢失数据更少)。AOF(Append Only File)是 Redis 另一种核心持久化机制,通过实时记录所有写命令(如 SET、HSET、LPUSH 等)实现数据备份,核心优势是数据一致性高(丢失数据量极少),适合对数据安全性要求严格的场景。
AOF 备份的核心原理
AOF 本质是 “命令日志的追加式存储”,其工作流程分为 3 个关键步骤:
- 记录命令:Redis 执行完每一条写命令后,会将命令(按 Redis 协议格式)追加到内存中的 “AOF 缓冲区”(避免频繁磁盘 IO)。
- 同步磁盘:根据配置的 “同步策略”,将 AOF 缓冲区的命令批量写入磁盘的
appendonly.aof文件(默认文件名)。 - 重写优化:随着时间推移,AOF 文件会因命令累积变得过大(如重复执行
INCR counter1000 次,文件会记录 1000 条命令),Redis 会通过BGREWRITEAOF重写文件 —— 将 “多个重复命令合并为最终结果命令”(如 1000 次INCR合并为SET counter 1000),大幅减小文件体积。
临时开启AOF备份
redis-cli -a 密码 CONFIG SET appendonly yes# 后台异步重写 AOF(不阻塞主线程),当 AOF 文件过大时,手动触发重写(避免自动重写在业务高峰期执行):
redis-cli -a 密码 BGREWRITEAOF# 查看重写进度(通过 INFO persistence 检查)
redis-cli -a 密码 INFO persistence | grep "aof_rewrite_in_progress"
# 输出 0 表示重写完成,1 表示正在重写# 等待重写完成后,复制到备份目录
cp /var/lib/redis/appendonly.aof /backup/redis/aof_$(date +%Y%m%d).aof# 检查并修复损坏的 AOF 文件
redis-check-aof --fix /var/lib/redis/appendonly.aofAOF 备份的核心配置(redis.conf)
AOF 需先在 redis.conf 中启用,关键配置决定其同步策略、文件路径和重写规则,直接影响数据安全性和性能:
| 配置项 | 作用 | 默认值 | 推荐配置 |
|---|---|---|---|
appendonly | 是否启用 AOF 持久化(核心开关) | no | yes(启用) |
appendfilename | AOF 备份文件名称 | appendonly.aof | 保持默认 |
dir | AOF 文件存储路径(与 RDB 共享同一目录) | /var/lib/redis | 与 RDB 一致 |
appendfsync | AOF 缓冲区同步到磁盘的策略(核心参数,平衡安全性与性能) | everysec | everysec |
no-appendfsync-on-rewrite | 重写 AOF 期间是否暂停同步(避免 IO 冲突) | no | yes(启用) |
auto-aof-rewrite-percentage | 自动重写触发条件:当前 AOF 文件大小比上一次重写后大多少百分比 | 100(2 倍) | 100 |
auto-aof-rewrite-min-size | 自动重写触发的最小文件大小(避免小文件频繁重写) | 64mb | 64mb |
关键配置详解:appendfsync(同步策略)
该配置决定 “命令从缓冲区写入磁盘的频率”,直接影响数据丢失风险和 IO 性能:
| 策略值 | 行为描述 | 数据安全性 | 性能影响 | 适用场景 |
|---|---|---|---|---|
always | 每执行一条写命令,立即同步到磁盘 | 最高(无丢失) | 极高(IO 密集) | 金融、支付等核心数据场景 |
everysec | 每秒同步一次(默认),将 1 秒内的命令批量写入磁盘 | 较高(最多丢 1 秒) | 中等 | 绝大多数生产场景(平衡安全与性能) |
no | 由操作系统决定同步时机(通常 30 秒一次) | 最低(可能丢大量数据) | 最低 | 非核心数 |
RDB vs AOF 选择建议
| 场景 | 推荐方式 | 理由 |
|---|---|---|
| 全量备份、快速恢复 | RDB | 文件体积小,恢复速度快 |
| 数据安全性要求高 | AOF | 支持每秒 / 每命令同步,丢失数据量可控制在毫秒级(配置 appendfsync always) |
| 混合使用(Redis 4.0+) | RDB + AOF | 结合 RDB 快速恢复和 AOF 高安全性(aof-use-rdb-preamble yes) |
二.redis-cluster的备份操作
1.获取所有主节点列表
redis-cli -a 密码 --cluster nodes 集群任意节点IP:端口 | grep -v "slave" | awk '{print $2}' | cut -d@ -f12.逐个主节点执行备份
# 遍历主节点,生成 RDB 并备份
for node in $(主节点列表); doip=$(echo $node | cut -d: -f1)port=$(echo $node | cut -d: -f2)echo "备份节点 $node..."redis-cli -h $ip -p $port -a 密码 BGSAVE# 等待备份完成(可通过 INFO persistence 查看 rdb_bgsave_in_progress 是否为 0)sleep 10# 复制 RDB 文件cp /var/lib/redis/$port/dump.rdb /backup/redis/cluster/${ip}_${port}_$(date +%Y%m%d).rdb
done三.redis-cluster的恢复操作
1.停止所有集群节点
for node in $(所有节点列表); doip=$(echo $node | cut -d: -f1)port=$(echo $node | cut -d: -f2)redis-cli -h $ip -p $port -a 密码 SHUTDOWN
done2.还原每个主节点的 RDB 文件
for node in $(主节点列表); doip=$(echo $node | cut -d: -f1)port=$(echo $node | cut -d: -f2)# 替换备份文件到节点数据目录(假设每个节点数据目录按端口区分)cp /backup/redis/cluster/${ip}_${port}_20240520.rdb /var/lib/redis/$port/dump.rdb
done3.还原每个主节点的AOF文件
for node in $(主节点列表); doip=$(echo $node | cut -d: -f1)port=$(echo $node | cut -d: -f2)# 替换备份文件到节点数据目录(假设每个节点数据目录按端口区分)cp /backup/redis/cluster/${ip}_${port}_20240520.aof /var/lib/redis/$port/appendonly.aof
done4.启动所有节点
for node in $(所有节点列表); doip=$(echo $node | cut -d: -f1)port=$(echo $node | cut -d: -f2)redis-server /etc/redis/$port.conf & # 按节点配置文件启动
done5.修复可能损坏的 AOF 文件(若恢复后启动失败)
redis-check-aof --fix /var/lib/redis/appendonly.aof6.验证集群状态
redis-cli -a 密码 --cluster check 集群任意节点IP:端口确保所有槽位正常分配(All 16384 slots covered),主从关系正确。
