redis是内存型的nosql数据库,当出现断电等异常会导致内存数据丢失,因此内存中的redis数据存在数据安全性。
为避免此情况的发生,需要将redis数据备份到磁盘中,此过程称为redis数据持久化
持久化方式:rdb和aof,rdb和aof分别为两种备份方式产生的数据文件的后缀名。
RDB
属于全量的持久化方式(默认持久化方式),修改redis.conf
#备份数据文件名称
dbfilename dump_8888.rdb
#备份文件存放路径
dir ./data/
#rdb文件格式校验
rdbchecksum yes
#是否压缩备份文件
rdbcompression yes
#是否异常后停止写入备份文件
stop-writes-on-bgsave-error yes
# xx秒内yy个key被修改时触发持久化
#save 900 1
#save 300 10
#save 60 10000
save 10 2
持久化过程: 在触发了持久化动作后,redis主进程会fork出一个子进程和当前redis的数据“快照”,完成此过程后主进程继续执行读写操作,子进程将生成的“快照”写入临时文件,写入完成后临时文件将代替原来的备份文件,子进程退出。
触发时机: 1. 达到配置文件中save的条件;
2. bgsave 执行指令 由子进程执行持久化;
3. save 指令 有主进程亲自执行持久化;
4. redis服务器正常关闭时。
注意事项: 1. 由于rdb属于全量备份,当数据量比较大时,创建子进程的时间会比较长,会造成redis的卡顿,需要谨慎设置save的参数,避免频繁触发备份。
2. rdb全量备份的特性使得rdb不适合做实时持久化。
3. 系统崩溃后会丢失自上次备份后的所有数据。
AOF
append only file,属于增量的方式执行数据持久化。
修改redis.conf配置文件
#开启aof备份方式
appendonly yes
#指定aof备份文件名称
appendfilename "appendonly-8888.aof"
#备份文件存放路径
dir ./data/
#设置触发备份时机,always:每次写命令就执行,I/O开销大;no:由操作系统决定备份时机,出现宕机等异常会损失不定量的数据;everysec:每秒执行一次备份(折中之选)
# appendfsync always
appendfsync everysec
# appendfsync no
持久化过程:redis将每一个执行成功的写命令写入aof文件(追加指令)。redis重启时只需要将aof文件从头到尾执行一遍即可恢复。
redis重启恢复数据时,如果rdb和aof文件同时存在,以aof为准。
触发时机:appendfsync 的配置参数
注意事项:1. aof文件会不断增长,会对磁盘造成压力。
2. redis重启时,执行一次非常大的aof文件会很耗时。
3. aof同步间隔短,理论上最多损失1秒的数据,相比rdb更适合做实时的持久化。
AOF重写
aof存在的问题:当不断追加指令,aof会越来越大,对磁盘产生压力的同时,redis恢复执行aof文件也会相当耗时,而且aof文件中的指令当对于最终数据来说,很多指令执行后对最终结果没有产生影响,比如 set name ‘xxx’,后又有del name,执行这些无用的命令只会浪费时间。
解决思路: 当aof追加指令达到一定体量时,重写aof中的所有指令。
aof重写:使用重写命令将redis现有数据转换成指令写入aof文件,以此替换原来的aof文件。
手动重写指令: bgrewriteaof
自动重写配置:redis.conf
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof文件大小超过64M,且体量比上次重写后增加了100%时触发aof重写。
比如上次重写后aof为40M,当体量再次超过64M且体量不小于2*40M时触发aof重写。
aof重写过程:
注意事项:1. 当前redis数据量很大时,创建子进程的过程会比较费时;
2. 替换aof文件时,如原aof文件很大,删除过程会比较费时。
RDB与AOF对比
RDB | AOF | |
占用存储空间 | 小(数据) | 大(指令) |
存储速度 | 慢 | 快 |
恢复速度 | 快 | 慢 |
数据安全性 | 会丢失数据 | 视写入策略而定 |
资源消耗 | 高 | 低 |
启动优先级 | 低 | 高 |