Redis是一个基于内存的数据库,它的数据是存放在内存中,内存有个问题就是关闭服务或者断电会丢失。Redis的数据也支持写到硬盘中,这个过程就叫做持久化。
RDB(Redis DataBase)
RDB在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是快照文件直接读到内存里。
Redis会单独创建(fork)一个子进程进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束后,再用这个临时文件替换上次持久化好的文件。Fork的作用是复制一个与当前进程一样的进程,新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致。
如果需要进行大规模的恢复,且对数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
代码语言:javascript复制指定备份文件的名称
dbfilename dump.rdb #在redis.conf中,可以修改rdb备份文件的名称,默认为dump.rdb
代码语言:javascript复制指定备份文件存放的目录
dir /var/local/backup/redis # 在redis.conf中,rdb文件的保存的目录是可以修改的,默认为Redis启动命令所在的目录
代码语言:javascript复制自动备份,在redis.conf中配置自动备份的规则
save 秒钟 写操作次数
save 3600 1 # 30分钟内修改了1次
save 300 100 # 5分钟内修改了10次
save 60 10000 # 1分钟内修改了1万次
save 20 3 #20秒内修改3次
代码语言:javascript复制手动执行命令备份(save|bgsave)
save:只管保存,其他不管,全部阻塞,手动保存,不建议使用
bgsave:redis会在后台异步进行快照操作,快照同时还可以响应客户端情况。
可以通过lastsave 命令获取最后一次成功生成快照的时间。
代码语言:javascript复制flushall备份
flushall:产生dump.rdb文件,但里面是空的,无意义。
代码语言:javascript复制redis.conf 配置
stop-writes-on-bgsave-error:当磁盘满时,是否关闭redis的写操作
rdbcompression:rdb备份是否开启压缩
rdbchecksum:是否检查rdb备份文件的完整性
代码语言:javascript复制rdb备份
config get dir # 查询rdb文件的目录
cp dump.rdb dump2.rdb # 将rdb的备份文件*.rdb 文件拷贝到别的地方
代码语言:javascript复制rdb恢复
systemctl stop redis #关闭redis
cp dump2.rdb dump.rdb #把备份的文件拷贝到工作目录
systemctl start redis #启动redis,备份数据直接加载,数据被恢复
代码语言:javascript复制RDB优势
1、适合大规模数据恢复
2、对数据完整性和一致性要求不高更适合使用
3、节省磁盘空间
4、恢复速度快
代码语言:javascript复制RDB劣势
1、Fork的时候,内存中的数据会被克隆一份,大致2倍的膨胀,需要考虑
2、Redis在fork的时候使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能
3、在备份周期在一定间隔时间做一次备份,所以如果Redis意外down的话,就会丢失最后一次快照后所有修改
代码语言:javascript复制停止RDB
redis-cli config set save "" # 动态停止RDB。save后给空值,表示禁用保存策略
AOF(Append Only File)
以日志的形式来记录每个写操作(增量保存),将redis执行过的所有写指令记录下来(读操作不记录),只允追加文件但不可改写文件,redis启动之初会读取该文件重新构造数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
代码语言:javascript复制1、AOF文件是一个只进行追加的日志文件
2、Redis可以在AOF文件体积变得过大时,自动地在后台对AOF文件进行重写,只保留可以恢复数据的最小指令集
3、AOF文件有序地保存了对数据库执行的所有写入操作,这些写入操作以redis协议的格式保存
4、对于相同的数据集来说,AOF文件的体积通常要大于RDB文件的体积
5、所使用的fsync策略,AOF的速度可能会慢于RDB
代码语言:javascript复制AOF持久化流程
1、客户端的请求写命令会被append追加到AOF缓冲区内
2、AOF缓冲区会根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中
3、AOF文件大小超过重写策略或手动重写时,会对AOF文件进行重写(rewrite),压缩AOF文件容量
4、redis服务器重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的
代码语言:javascript复制在redis.conf文件中开启AOF
appendonly no # 是否开启AOF,yes:开启,no:不开启,默认为no
appendfilename "appendonly.aof" # aof文件名称,默认为appendonly.aof
dir ./ #aof文件所在目录,默认./,表示执行启动命令时所在的目录
# AOF和RDB同时开启,系统默认取AOF的数据(数据不会存在丢失)
代码语言:javascript复制AOF启动/修复/恢复
1、正常恢复
修改默认的appendonly no,改为yes
将有数据的aof文件复制一份保存到对应的目录(查看目录:config get dir)
恢复:重启redis然后重新加载
2、异常恢复
修改默认的appendonly no,改为yes
如遇到aof文件损坏,通过/usr/local/bin/redis-check-aof --fix appendonly.aof进行恢复
代码语言:javascript复制在redis.config中配置AOF同步的频率
appendfsync always:# 始终同步,每次redis的写入都会立刻记入日志;性能较差但数据完整性比较好
appendfsync everysec:每秒同步
appendfsync no:redis不主动进行同步,把同步交给操作系统
代码语言:javascript复制AOF文件压缩
AOF采用文件追加方式,文件会越来越大,为了避免出现此情况,新增了重写机制
当AOF文件的大小超过锁审定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集
可以使用命令bgrewriteaof触发重写
bgrewriteaof:手动触发重写 # Redis 2.4 开始, AOF 重写由 Redis 自行触发。
# 默认配置是当aof文件大小是上次rewrite后大小的2倍且文件大于64M时触发。
auto-aof-rewrite-percentage:设置重写基准值 # 默认100,当文件达到100%时开始重写
auto-aof-rewrite-min-size:设置重写基准值 # 默认64MB,AOF文件大小超过这个值开始重写
no-appendfsync-on-rewrite:重写时,不会执行appendfsync操作
代码语言:javascript复制AOF优势
1、备份机制更稳健,丢失数据概率更低
2、可读的日志文本,通过操作AOF文件,可以处理误操作
代码语言:javascript复制AOF劣势
1、比RDB占用更多的磁盘空间
2、恢复备份速度要慢
3、每次读写都同步的话,有一定的性能压力
4、存在个别bug,造成不能恢复
总结
代码语言:javascript复制1、推荐启用RDB和AOF
2、如果对数据不敏感,可以单独用RDB
3、不建议单独使用AOF,因为可能会出现BUG
4、RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1 这一条
5、如果使用AOF,好处是在最恶劣的情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了
6、AOF的代价,一是带来持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据(aof_rewrite_buf)写到文件造成的阻塞几乎是不可避免的
7、只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基数大小默认值64M(auto-aof-rewrite-min-size)太小了,可以设置到5G以上
8、默认超过原大小100%(auto-aof-rewrite-percentage)大小时重写可以改到适当的数值