redis之持久化

简介

redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。

RDB,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上

AOF,就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。

其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。

如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache一样。

redis持久化 – RDB

RDB方式,是将redis某一时刻的数据持久化到磁盘中,是一种快照式的持久化方法。

RDB的触发方式

手动触发

  1. bgsave命令阻塞只发生在fork主进程时,时间极短,建议使用;
  2. save命令阻塞时间为整个持久化过程,不建议使用。

自动触发

  1. 在redis配置文件中启用save配置,如“save m n”,即m秒内发生n次变动则自动触发bgsave
  2. 从节点执行全量复制,则redis主节点执行bgsave生成文件发给从节点
  3. 执行debug reload重新加载redis
  4. 使用shutdown关闭redis,如果没有开启AOF则使用bgsave

RDB的工作流程

在这里插入图片描述

  1. redis主进程接收并准备执行bgsave命令
  2. 主进程阻塞,进行fork操作生成子进程,大约微秒
  3. 成功生成子进程,主进程阻塞结束继续接收并执行其他命令
  4. 子进程对主进程内存中的数据开始写入到一个临时文件,待写完后替换原有的RDB文件
  5. 通知主进程RDB持久化结果,主进程更新统计信息。

对于RDB方式,redis会单独创建(fork)一个子进程来进行持久化,而主进程继续响应请求而不会进行任何IO操作的,这样就确保了redis极高的性能。

如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。

虽然RDB有不少优点,但它的缺点也是不容忽视的。如果你对数据的完整性非常敏感,那么RDB方式就不太适合你,因为即使你每5分钟都持久化一次,当redis故障时,仍然会有近5分钟的数据丢失。所以,redis还提供了AOF。

RDB文件处理

保存
RDB文件保存在配置dir指定目录下,文件名以配置dbfilename指定。
可通过命令config set dir NEW-DIR和config set dbfilename NEW-DBFILENAME,动态进行修改目录和文件名;下次RDB发生时应用新目录和文件名

压缩
默认开启对RDB的压缩,使得数据文件远小于内存中的大小,有利于硬盘空间的节约和在网络中的传输。
配置rdbcompression yes|no

校验
加载有问题的RDB文件,redis会拒绝启动并报错如下:
short read or OOM loading DB,Unrecoverable error,abouting now

redis持久化 – AOF

AOF,英文是Append Only File,即只允许追加不允许改写的文件。

AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍。

通过配置中的appendonly yes就可以打开AOF功能。如果有写操作(如SET等),redis就会被追加到AOF文件的末尾。

AOF工作流程

在这里插入图片描述

  1. 将写操作的命令写入到redis的aof缓存区中,直接文本的形式写入,好处是减少cpu开销和便于后面查看和修改。
  2. AOF缓存区根据策略同步到磁盘中的AOF文件,开辟aof缓存区而不直接写入到磁盘中,是为了减少redis主进程受磁盘性能影响
  3. AOF文件随着运行越来越大,这时候就需要进行AOF重写。AOF重写会将内存中的数据以写命令的形式同步到AOF文件中。具体流程后面讲解
  4. redis重启加载并执行AOF文件中的命令

默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,redis仍然可以保持很好的处理性能,即使redis故障,也只会丢失最近1秒钟的数据。

AOF方式的好处,我们通过一个“场景再现”来说明。某同学在操作redis时,不小心执行了FLUSHALL,导致redis内存中的数据全部被清空了,这是很悲剧的事情。不过这也不是世界末日,只要redis配置了AOF持久化方式,且AOF文件还没有被重写(rewrite),我们就可以用最快的速度暂停redis并编辑AOF文件,将最后一行的FLUSHALL命令删除,然后重启redis,就可以恢复redis的所有数据到FLUSHALL之前的状态了。是不是很神奇,这就是AOF持久化方式的好处之一。但是如果AOF文件已经被重写了,那就无法通过这种方法来恢复数据了。

虽然优点多多,但AOF方式也同样存在缺陷,比如在同样数据规模的情况下,AOF文件要比RDB文件的体积大。而且,AOF方式的恢复速度也要慢于RDB方式。

如果你直接执行BGREWRITEAOF命令,那么redis会执行AOF重写生成一个全新的AOF文件,其中便包括了可以恢复现有数据的最小的命令集。

如果运气比较差,AOF文件出现了被写坏的情况,也不必过分担忧,redis并不会贸然加载这个有问题的AOF文件,而是报错退出。这时可以通过以下步骤来修复出错的文件:
1.备份被写坏的AOF文件
2.运行redis-check-aof –fix进行修复
3.用diff -u来看下两个文件的差异,确认问题点
4.重启redis,加载修复后的AOF文件

AOF重写

AOF重写的AOF持久化的一个重要流程,我们有必要了解一下。

AOF重写的触发

手动触发用户执行bgrewriteaof命令
自动触发根据aut-aof-rewrite-min-size和auto-aof-rewrite-rewrite-percentage参数进行某种公式计算

AOF重写工作流程

在这里插入图片描述

  1. 在重写即将开始之际,redis会创建(fork)一个“重写子进程”。此时阻塞等待fork完成
  2. 主进程生成子进程后,将接收到的写命令送入两个缓存区中,AOF缓存区用于追加到旧AOF文件中;AOF重写缓存区是为了保证重写期间的数据仍能写入到新AOF文件中。
  3. 子进程生产新的AOF文件;父进程将AOF重写缓存区同步到新AOF文件中
  4. 待重写结束后替代旧文件
  5. 当“重写子进程”完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中。

对于我们应该选择RDB还是AOF,官方的建议是两个同时使用。这样可以提供更可靠的持久化方案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值