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

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

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

RDB方式vim

  • 当符合必定条件时,
    • 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的重写原理app

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