Redis的数据是如何持久化的?

Redis的数据是如何持久化的?

  • 一种是RDB方式、
    • 则“定时”将内存中的数据存储在硬盘上
  • 另一种是AOF(append-only-file)方式。
    • 在每次执行命令后将命令本身记录下来
  • 两种持久化方式可以单独使用其中一种,
    • 也可以将这两种方式结合使用

RDB方式

  • 当符合一定条件时,
    • Redis会单独创建(fork)一个子进程来进行持久化,
    • 会先将数据写入到一个临时文件中,等到持久化过程都结束了,
    • 再用这个临时文件替换上次持久化好的文件。
  • 整个过程中,主进程是不进行任何IO操作的,
    • 这就确保了极高的性能。
  • RDB的缺点是最后一次持久化后的数据可能丢失
  • --fork的作用是复制一个与当前进程一样的进程。

Redis会在以下几种情况下对数据进行快照

  • 根据配置规则进行自动快照
    • Redis允许用户自定义快照条件,
      • 当符合快照条件时,Redis会自动执行快照操作
    • 配置格式如下:
      • save 900 1
        • 第一个参数是时间窗口,第二个是键的个数
        • 在900秒(15分)内有一个以上的键被更改则进行快照。
        • 每条快照规则占一行,每条规则之间是“或”的关系
  • 用户执行SAVE或者GBSAVE命令
    • 当我们对服务进行重启或者服务器迁移我们需要人工去干预备份
    • redis提供了两条命令来完成这个任务
      • save命令
        • 当执行save命令时,Redis同步做快照操作,
          • 在快照执行过程中会阻塞所有来自客户端的请求。
        • 当redis内存中的数据较多时,
          • 通过该命令将导致Redis较长时间的不响应。
          • 所以不建议在生产环境上使用这个命令,
          • 而是推荐使用bgsave命令
      • bgsave命令
        • bgsave命令可以在后台异步地进行快照操作,
          • 快照的同时服务器还可以继续响应来自客户端的请求
          • 执行BGSAVE后,Redis会立即返回ok表示开始执行快照操作
    • 通过LASTSAVE命令可以获取最近一次成功执行快照的时间;
      • 自动快照采用的是异步快照操作
  • 执行FLUSHALL命令
    • 会清除redis在内存中的所有数据
    • 执行该命令后,只要redis中配置的快照规则不为空,也就是save 的规则存在。
      • redis就会执行一次快照操作。
      • 不管规则是什么样的都会执行。
      • 如果没有定义快照规则,就不会执行快照操作
  • 执行复制(replication)时
    • 在主从模式下,redis会在复制初始化时进行自动快照。
    • 这里只需要了解当执行复制操作时
      • 即使没有定义自动快照规则,并且没有手动执行过快照操作,
      • 它仍然会生成RDB快照文件

AOF方式

  • 当使用Redis存储非临时数据时,
    • 一般需要打开AOF持久化来降低进程终止导致的数据丢失。
  • AOF可以将Redis执行的每一条写命令追加到硬盘文件中,
    • 这一过程会降低Redis的性能,
    • 但大部分情况下这个影响是能够接受的,
    • 另外使用较快的硬盘可以提高AOF的性能
  • 开启AOF
    • 默认情况下Redis没有开启AOF
    • 可以通过appendonly参数启用,
      • 在redis.conf 中找到 appendonly yes
    • 开启AOF持久化后
      • 每执行一条会更改Redis中的数据的命令后
        • Redis就会将该命令写入硬盘中的AOF文件。
  • AOF文件的保存位置和RDB文件的位置相同,
    • 都是通过dir参数设置的,
      • 默认的文件名是apendonly.aof.
    • 可以在redis.conf中的属性 appendfilename  appendonlyh.aof修改
  • AOF的实现
    • AOF文件以纯文本的形式记录Redis执行的写命令
    • 通过vim的方式可以看到aof文件中的内容
      • set foo 1
        set foo 2
        set foo 3
        get
      • 从内容中我们发现Redis只记录了3 条命令
        • get 未记录
      • 这时有一个问题是前面2条命令其实是冗余的
      • 随着执行的命令越来越多,AOF文件的大小也会越来越大,
        • 其实内存中实际的数据可能没有多少
      • 因此我们希望Redis可以自动优化AOF文件
      • 实际上Redis也考虑到了,可以配置一个条件,
        • 每当达到一定条件时Redis就会自动重写AOF文件,
        • 这个条件的配置问 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
        • auto-aof-rewrite-percentage
          • 表示的是当目前的AOF文件大小
          • 超过上一次重写时的AOF文件大小的百分之多少时
          • 会再次进行重写,如果之前没有重写过,
          • 则以启动时AOF文件大小为依据
        • auto-aof-rewrite-min-size
          • 表示限制了允许重写的最小AOF文件大小,
          • 通常在AOF文件很小的情况下
            • 即使其中有很多冗余的命令我们也并不太关心。
      • BGREWRITEAOF 命令手动执行AOF,
        • 执行完以后冗余的命令已经被删除了
        • 在启动时,Redis会逐个执行AOF文件中的命令来将硬盘中的数据载入到内存中,
          • 载入的速度相对于RDB会慢一些

AOF的重写原理

  • 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。
  • 重写的流程是这样,
    • 主进程会fork一个子进程出来进行AOF重写,
    • 这个重写过程并不是基于原有的aof文件来做的,
      • 而是有点类似于快照的方式,全量遍历内存中的数据,
      • 然后逐个序列到aof文件中。
    • 在fork子进程这个过程中,服务端仍然可以对外提供服务
      • 这个过程中,主进程的数据更新操作,会缓存到aof_rewrite_buf中,
        • 也就是单独开辟一块缓存来存储重写期间收到的命令,
        • 当子进程重写完以后再把缓存中的数据追加到新的aof文件。
      • 当所有的数据全部追加到新的aof文件中后,把新的aof文件重命名,
        • 此后所有的操作都会被写入新的aof文件。
      • 如果在rewrite过程中出现故障,不会影响原来aof文件的正常工作,
        • 只有当rewrite完成后才会切换文件。
        • 因此这个rewrite过程是比较可靠的

转载于:https://my.oschina.net/u/3847203/blog/3023042

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值