redis的持久化
redis是一个内存数据库,就是将数据内容存储在内存中,这与传统关系型数据库直接将数据保存到硬盘中相比,数据读取速度要比传统数据库快很多。但保存在内存中有个缺点,就是一旦系统宕机或者重启,那么内存中的数据就会全部丢失。redis提供了将内存数据持久化到硬盘的方式。Redis 支持两种形式的持久化,一种是RDB快照(snapshotting),另外一种是AOF(append-only-file),本篇主要介绍redis持久化内容
RDB简介
- RDB是对redis中的数据执行周期性的持久化,把当前内存中的数据集快照写入磁盘,也就是 Snapshot 快照(数据库中所有键值对数据)。恢复时是将快照文件直接读到内存里。
RDB工作流程
1.redis根据配置自己尝试去生成rdb快照文件
2.fork一个子进程出来
3.子进程尝试将数据dump到临时的rdb快照文件中
4.完整的rdb快照文件生成之后,就替换之前的旧的快照文件
RDB触发方式
- 自动触发
- 配置文件内用save,格式为"save m n",表示m秒内数据存在n次修改时,自动触发bgsave
- 手动触发
- save 该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。显然该命令对于内存比较大的实例会造成长时间阻塞,这是致命的缺陷,为了解决此问题,Redis提供了第二种方式。
- bgsave 执行该命令时,Redis会在后台异步进行快照操作,执行快照同时还可以响应客户端请求。具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。redis内部所有rdb操作都是采用bgsave
恢复数据
- 将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可,redis就会自动加载文件数据至内存了。Redis 服务器在载入 RDB 文件期间,会一直处于阻塞状态,直到载入工作完成为止。
停止rdb
- 在redis.conf 中,注释掉所有的 save 行来停用快照功能或者直接一个空字符串来实现停用:save ""
- 命令行配置
>config set save " "
RDB优点
1.RDB会生成多个数据文件,每个数据文件都代表某一时刻redis中的数据,此种方式,非常适合做冷备份,可以将这种完整的数据文件放到安全存储上面去,如s3或者阿里云的odps
2.RDB对redis对外提供的读写服务,影响非常小,可以让redis保持高性能,因为redis主进程只需要fork一个子进程,让子进程执行磁盘io操作来进行rdb持久化
3.相对于AOF持久化机制,直接基于RDB数据文件来重启和恢复redis进程更加快速
RDB缺点
1.想在redis故障时,尽可能丢失最少的数据,RDB没有AOF好,一般来说RDB的快照文件都是每隔5分钟,或者更长时间生成一次数据,一旦故障,会丢失最近5分钟的数据
2.RDB每次在fork子进程来执行RDB快照时,如果数据文件很大,可能会导致对客户端提供的服务暂停数毫秒,甚至数秒
3.最大缺点是不适合做第一优先的恢复方案,如果依赖RDB做第一恢复方案,数据丢失会比较多
AOF 简介
- AOF 是通过保存Redis服务器所执行的写命令来记录数据库状态。对redis中每条写入命令做日志,以append-only的模式写入一个日志文件中,在redis重启时,通过回放AOF日志中的写入命令来重建数据集
- 现代操作系统中,写文件不是直接写入磁盘的,会先写 os cache,然后定期写入磁盘,aof会每个一段时间写数据到os cache,定期调用操作系统的fsync操作,将OS cache中数据刷入磁盘文件中,aof会导致日志持久化文件越来越大,当大到一定的时候,
- AOF会做rewrite操作,rewrite操作会基于当时内存中的数据来构造一个更小的AOF文件,然后将旧的文件删除,此时新的AOF文件会丢失掉被LRU算法淘汰掉的那部分数据,redis会有限定的内存大小,到达最大值时,会使用LRU算法淘汰掉一部分数据
AOF的工作流程
1.redis fork一个子进程
2.子进程基于当前内存中的数据,构建日志,开始向一个新的临时的AOF文件中写日志
3.redis主进程接收到client新的写操作之后,在内存中写入日志,同时新的日志也继续写入旧的aof文件
4.子进程写完新的日志文件之后,主进程将内存中的新日志再次追加到新的AOF文件中
5.用新的日志文件替换掉旧的日志文件
AOF 配置
- 要开启 AOF 持久化方式,需要在配置文件中将 appendonly 修改为 yes。
- appendfilename :aof文件名,默认是"appendonly.aof"
- appendfsync:aof持久化策略的配置;
1.no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快,但是不太安全;
2.always表示每次写入都执行fsync,以保证数据同步到磁盘,效率很低;
3.everysec表示每秒执行一次fsync,可能会导致丢失这1s数据。通常选择 everysec ,兼顾安全性和效率。
AOF 优点
1.可以更好的保护数据不丢失,一般AOF会每隔1秒钟,通过一个后台线程执行一次fsync操作,最多丢失1秒的数据
2.AOF以append-only模式写入,所以没有磁盘寻址开销,写入性能非常高,而且文件不易破损,即使破损,也容易修复,破损也是文件尾部破损,redis提供有工具修复
3.AOF文件即使过大,出现后台重写操作,也不会影响客户端的读写,因为rewrite log时,会进行压缩,创建出一份需要恢复的最小日志出来,在创建新日志的时候,老的日志文件还是照常写入,当新的merge后的日志文件ready的时候,在交换新老日志文件即可
4.AOF日志文件通过非常可读的方式进行记录,此特性适合做灾难性的误删除的紧急恢复,比如用flushall清空了所有数据,只要此时后台rewrite还没有发生,就可以立即拷贝AOF文件,将最后一条执行的flushall命令删除,再将AOF日志文件放回去,通过恢复机制,自动恢复所有数据。
AOF 缺点
1.对于同一份数据来说,AOF文件通常比RDB文件更大
2.AOF开启后,支持的QPS会比RDB低,因为AOF一般配置每1秒fsync一次日志文件
3.AOF发生过bug,进行数据恢复时,没有恢复一模一样的数据,类似AOF这种较为复杂的基于命令日志/merge/回放的方式,比基于RDB每次持久化一份数据的方式更脆弱一些,AOF为了避免rewrite过程导致的bug,每次rewrite并不是基于旧的指令日志进行merge的,而是基于当时内存中的数据进行指令的重新构建,这样健壮性更好些。
4.数据恢复会比较慢
总结
1.AOF也可以用于做冷备份,每隔一定时间去copy这份数据
2.rdb做冷备份是由redis控制生成快照文件,AOF要写脚本,定时任务才能实现
3.RDB快照生成间隔周期要短,否则丢失的数据多,恢复时对客户端影响也大(数据大会导致客户端服务暂停一段时间)
4.如果保证一条数据不丢,可以将fsync设置成每写一个命令,就fsync一次,但此时redis的QPS会大幅降低
5.如果想让redis仅仅当做纯内存的缓存来使用,那么可以禁止RDB和AOF的持久化机制
6.通过持久化机制,可以把redis内存中的数据持久化到磁盘上,然后可以将这些数据备份到别的地方去,比如阿里云
7.如果同时使用了RDB和AOF两种持久化机制,那么在redis重启的时候,会使用AOF来重新构建数据,因为AOF中的数据更完整
redis企业级备份方案
- 数据备份方案:
1.写定时任务脚本
2.每小时copy一份rdb到一个目录,仅仅保留最近48小时的备份
3.每天都保留一份当日的备份,保留最近一个月的备份
4.每次copy备份的时候,把旧备份删除
5.每天晚上将当前服务器上所有的数据备份发送一份到远程的云服务上去
- 数据恢复:
1.如果是redis进程挂掉,重启redis,会基于aof恢复数据
2.如果redis所在的机器挂掉,重启机器,重启redis
3.如果最新的rdb和aof文件出现丢失或破损,可以基于当前机器最新的rdb数据副本进行恢复
4.如果有重大数据错误,比如程序存在bug,将redis数据污染了,可以选择某个更早的时间点,对数据进行恢复
- 使用rdb数据备份恢复数据时,要关闭aof功能,否则,redis会基于aof恢复数据,而不是rdb
参考文档:
1.https://www.cnblogs.com/ysocean/p/9114267.html
2.https://redis.io/topics/persistence
网友评论