Redis数据持久化机制及数据恢复
什么是数据持久化?
我们知道Redis是基于内存的非关系型数据库,对数据的增删改查操作都直接在内存中进行,再加上Redis不用维护数据之间的“关系”,导致它性能很高,速度很快。
但是基于内存有一个问题是:一旦机器断电,内存中的数据会丢失。
数据丢失是很严重的问题,所以Redis是支持数据持久化的。
数据持久化:将内存中的数据写入到磁盘,数据永久保存。
Redis的持久化机制
Redis支持两种持久化机制:RDB和AOF,4.0版本以后还加入了混合持久化机制。
RDB持久化
RDB全称:Redis DataBase。
RDB是Redis默认的持久化机制,在指定的时间间隔内,进行了指定次数的写操作,Redis就会触发RDB持久化,RDB持久化的是数据的二进制文件,节省空间。
Redis会fork一个和主进程一模一样的子进程,子进程将内存中的所有数据先写入到一个临时文件中,持久化结束以后,将这个临时文件替换正式的dump.rdb文件,整个持久化的过程中主进程不进行任何磁盘IO操作,这就确保了Redis极高的性能。
持久化文件存放在哪里?
redis.conf文件中的dir配置的目录 + dbfilename配置的文件名。
RDB触发时机
- 在指定的时间间隔内,执行指定次数的写操作。
- 手动执行save、bgsave时。
- 执行FlushAll命令时,数据是空的,没有意义。
- shutdown时,如果没有开启AOF就会触发。
- 主从复制时。
save和bgsave
-
save
阻塞当前Redis服务,直到持久化完成,期间所有请求都会被阻塞,线上一般不使用。 -
bgsave
Redis服务不受影响,fork一个子进程去异步的持久化,将内存数据写到到临时文件,持久化完成后替换dump.rdb文件。
RDB的优缺点
优点
- 性能高
- RDB文件占用空间小
- 数据恢复很快
缺点
- 数据完整性和一致性要求不高,可能丢失数据。
- 备份时占用内存,fork的子进程会让内存突然飙升。
AOF持久化
AOF全称:Append Only File。
AOF持久化在Redis中默认是关闭的,需要手动开启,AOF的出现是为了弥补RDB的不足。
AOF通过追加日志的方式来做持久化,将涉及到数据增删改的命令以日志的方式追加到aof文件中,Redis服务重启时执行一遍aof中的命令来完成数据的恢复。
如何开启AOF
修改配置文件,重启服务。
# 开启AOF
appendonly yes
# aof文件名
appendfilename "appendonly.aof"
# AOF触发时机:
# always 每次写操作都写入磁盘,效率低。
# everysec 每秒写入一次磁盘。
# no Redis不主动写磁盘,由操作系统来决定调用,线上不推荐使用。
# appendfsync always
appendfsync everysec
# appendfsync no
AOF重写机制
因为AOF文件存储的是命令,就导致它比较庞大,比rdb文件要大很多,Redis需要对其进行“瘦身”。
AOF重写就是对AOF文件进行“瘦身”,采用的方案是:将多条写操作优化为一条写操作,记录最终结果,而无需记录中间每一步的操作记录,重写之后AOF文件会小很多。
如下例子:
rpush a 1
rpush a 2
rpush a 3
重写后:
rpush a 1 2 3 (3条命令变成1条)
配置AOF重写策略
# 当AOF文件大小的增长率大于该配置项时触发重写。
auto-aof-rewrite-percentage 100
# 当AOF文件大小大于此配置时,触发重写。线上环境要调大该值。
auto-aof-rewrite-min-size 64mb
手动触发AOF重写
BGREWRITEAOF
混合持久化机制
Redis4.0版本推出了混合持久化机制,5.0之前默认关闭,5.0版本已经默认开启了。
修改配置文件开启
aof-use-rdb-preamble yes
混合持久化是通过BGREWRITEAOF来实现的,未开启混合持久化时,AOF重写的方式是将多条指令优化为一条,开启混合持久化后,AOF前半段是RDB格式的二进制数据全量文件,后半段以日志命令的方式追加,AOF文件也采用混合存储。
数据恢复
Redis重启后,需要对数据进行恢复,将RDB/AOF中持久化的数据重新加载到内存,步骤大致如下图所示: