昨天华为云 Redis 迁移下云,我来做数据迁移,我第六感优先使用了 RDB 的方式来拿取备份并恢复数据,RDB 恢复是需要重启的 Redis 服务的,需要 Redis 重新读取 RDB 文件,然后业务出问题了,领导问我怎么恢复的,我说 RDB ,领导就说怎么要用 RDB 啊,在线恢复就好了啊。
我惊讶了,因为平时操作 Redis 较少,甚至也忘了 RDB 和 AOF 的区别,更别提在线迁移数据了。然后在本文浅浅的记录一下,关于 Redis 备份恢复的问题。
RDB 和 AOF 的区别
这是 Redis 的两种持久化方式,RDB 为快照方式,AOF 为操作记录日志的方式(类似 MySQL binlog)
RDB
RDB 是 Redis 默认的持久化方式,在指定的时间间隔内将内存中的数据集快照写入磁盘,也可以将快照复制到其他的 Redis 实例进行数据恢复。RDB 持久化会生成 RDB 文件,这是一个压缩过的二进制文件,默认为 Redis 实例目录下的 dump.rdb
,可以根据 redis.conf 配置文件中的dbfilename
和dir
设置RDB的文件名和文件位置。
AOF
AOF 持久化会把被执行的写命令写到 AOF 文件的末尾,记录数据的变化。默认情况下,Redis是没有开启 AOF 持久化的,开启后,每执行一条更改Redis数据的命令,都会把该命令追加到 AOF 文件中,这是会降低 Redis 的性能,但大部分情况下这个影响是能够接受的,另外使用较快的硬盘可以提高 AOF 的性能。
RDB 备份
有几个操作会触发生成 RDB 文件
- 执行
save
和bgsave
命令 - 配置文件设置
save <seconds> <changes>
规则,自动间隔性执行bgsave
命令 - 主从复制时,从库全量复制同步主库数据,主库会执行
bgsave
- 执行
flushall
命令清空服务器数据 - 执行
shutdown
命令关闭Redis时,会执行save
命令
登录 redis 客户端执行 save
和bgsave
手动触发生成 RDB 文件
使用save
命令会阻塞 Redis 服务器进程,服务器进程在 RDB 文件创建完成之前是不能处理任何的命令请求
127.0.0.1:6379> save
OK
bgsave
命令会fork
一个子进程,然后该子进程会负责创建 RDB 文件,而服务器进程会继续处理命令请求。
127.0.0.1:6379> bgsave
Background saving started
redis.conf
save 900 1
save 300 10
save 60 10000
save <seconds> <changes>
表示在seconds秒内,至少有changes次变化,就会自动触发gbsave
命令
save 900 1
当时间到900秒时,如果至少有1个key发生变化,就会自动触发bgsave
命令创建快照save 300 10
当时间到300秒时,如果至少有10个key发生变化,就会自动触发bgsave
命令创建快照save 60 10000
当时间到60秒时,如果至少有10000个key发生变化,就会自动触发bgsave
命令创建快照
RDB 恢复
检查配置文件
# 表示 redis.conf 同级目录的 dump.rdb
dir ./
dbfilename dump.rdb
进入 Redis 客户端再次确认读取/备份 RDB 文件的目录
127.0.0.1:6379> CONFIG GET dir
停止服务
redis-cli -p 6379 shutdown -a '密码'
将备份好的 RDB 文件复制到 redis 实例目录下,如果有同名的 dump.db
最好先备份一个
重启 redis 即可
redis-server redis.conf
AOF 备份
配置文件开启持久化
redis.conf
# appendonly参数开启AOF持久化
appendonly yes
# AOF持久化的文件名,默认是appendonly.aof
appendfilename "appendonly.aof"
# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的
dir ./
# 同步策略
appendfsync everysec
# aof重写期间是否同步
no-appendfsync-on-rewrite no
# 重写触发配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 加载aof出错如何处理
aof-load-truncated yes
# 文件重写策略
aof-rewrite-incremental-fsync yes
同步策略
appendfsync选项的默认配置为everysec,即每秒执行一次同步
always:将aof_buf缓冲区的所有内容写入并同步到AOF文件,每个写命令同步写入磁盘
everysec:将aof_buf缓存区的内容写入AOF文件,每秒同步一次,该操作由一个线程专门负责
no:将aof_buf缓存区的内容写入AOF文件,什么时候同步由操作系统来决定
选项时为always
时,数据安全性是最高的,但是会对磁盘进行大量的写入,Redis处理命令的速度会受到磁盘性能的限制;appendfsync everysec
选项则兼顾了数据安全和写入性能,以每秒一次的频率同步AOF文件,即便出现系统崩溃,最多只会丢失一秒内产生的数据;如果是appendfsync no
选项,Redis不会对AOF文件执行同步操作,而是有操作系统决定何时同步,不会对Redis的性能带来影响,但假如系统崩溃,可能会丢失不定数量的数据
AOF 重写
随着时间的推移,Redis执行的写命令会越来越多,AOF文件也会越来越大,过大的AOF文件可能会对Redis服务器造成影响,如果使用AOF文件来进行数据还原所需时间也会越长。
时间长了,AOF文件中通常会有一些冗余命令,比如:过期数据的命令、无效的命令(重复设置、删除)、多个命令可合并为一个命令(批处理命令)。所以AOF文件是有精简压缩的空间的。
AOF重写的目的就是减小AOF文件的体积,不过值得注意的是:AOF文件重写并不需要对现有的AOF文件进行任何读取、分享和写入操作,而是通过读取服务器当前的数据库状态来实现的
文件重写可分为手动触发和自动触发,手动触发执行bgrewriteaof
命令,该命令的执行跟bgsave
触发快照时类似
127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started
自动触发会根据auto-aof-rewrite-percentage
和auto-aof-rewrite-min-size 64mb
配置来自动执行bgrewriteaof
命令
# 表示当AOF文件的体积大于64MB,且AOF文件的体积比上一次重写后的体积大了一倍(100%)时,会执行`bgrewriteaof`命令
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
- 在重写期间,服务器进程继续处理命令请求,如果有写入的命令,追加到
aof_buf
的同时,还会追加到aof_rewrite_buf
AOF重写缓冲区 - 当子进程完成重写之后,会给父进程一个信号,然后父进程会把AOF重写缓冲区的内容写进新的AOF临时文件中,再对新的AOF文件改名完成替换,这样可以保证新的AOF文件与当前数据库数据的一致性
AOF 在线恢复
检查配置文件
appendonly yes
appendfilename "appendonly.aof" # 指定aof文件名
dir ./ # 这里和dump.rdb指向同一个目录
此恢复不需要停止 redis 服务
# 清空数据
redis-cli -h 192.168.1.1 -p 6379 -a '密码' flushall
# 将 aof 备份文件放到指定目录
# 数据导入
redis-cli -h 192.168.1.1 -p 6379 -a '密码' --pipe < appendonly.aof
当然同样可以通过重启服务的方式重新读取 aof 文件。
如何选择RDB和AOF
如果是数据不那么敏感,且可以从其他地方重新生成补回的,那么可以关闭持久化
如果是数据比较重要,不想再从其他地方获取,且可以承受数分钟的数据丢失,比如缓存等,那么可以只使用RDB
如果是用做内存数据库,要使用Redis的持久化,建议是RDB和AOF都开启,或者定期执行bgsave
做快照备份,RDB方式更适合做数据的备份,AOF可以保证数据的不丢失