当前位置: 首页 > news >正文

Redis 持久化详解

目录

    • 一、简介
    • 二、RDB持久化
      • 2.1、SAVE
      • 2.2、BGSAVE
      • 2.3、SAVE选项
      • 2.4、RDB文件结构
      • 2.5、RDB文件载入
    • 三、AOF持久化
      • 3.1、开启AOF功能
      • 3.2、配置AOF文件的冲洗频率
      • 3.3、AOF重写
        • 3.3.1、BGREWRITEAOF命令(手动)
        • 3.3.2、AOF重写配置选项(自动)
    • 四、RDB-AOF混合持久化
      • 4.1、RDB和AOF的优劣
      • 4.2、开启RDB-AOF混合持久化
      • 4.3、RDB-AOF混合持久化文件载入
    • 结语

一、简介

  本文今天主要是Redis的持久化方式,都是关于RDBAOF,常见的持久方式有:

  • RDB持久化
  • AOF持久化
  • RDB-AOF混合持久化

二、RDB持久化

  RDB持久化是Redis默认使用的持久化功能,该功能可以创建出一个经过压缩的二进制文件,它包含了服务器在各个数据库中存储的键值对数据等信息。RDB持久化产生的文件都以 .rdb 后缀结尾,其中 rdb 代表Redis DataBase(Redis数据库)。Redis提供了多种创建RDB文件的方法,主要是下面三种:

  • SAVE(阻塞服务器并创建RDB文件)
  • BGSAVE(以非阻塞方式创建RDB文件)
  • 通过配置选项自动创建RDB文件

2.1、SAVE

  用户可以通过执行SAVE命令,要求Redis服务器以同步方式创建一个记录了服务器当前所有数据库数据的RDB文件,这里使用的是无参命令。

127.0.0.1:6379> save
OK

  服务器接收到SAVE命令,将遍历所有数据库,并将各个数据库包含的键值对全部记录到RDB文件中。在执行SAVE命令期间,Redis服务器将阻塞,直到RDB文件创建完成为止。如果Redis服务器在执行SAVE命令时已经拥有了相应的RDB文件,那么服务器将使用新创建的RDB文件替换已有的RDB文件,大致流程如下:

在这里插入图片描述

2.2、BGSAVE

  我们知道Redis在执行SAVE命令时,会阻塞整个服务器,无法为其他客户端提供服务,如果数据量很大,阻塞就更严重了,所以为了解决这个问题,Redis提供了SAVE命令的异步版本BGSAVE命令,它们不同之处在于,BGSAVE命令不会使用Redis的服务进程创建RDB文件,而是使用子进程创建RDB文件。

127.0.0.1:6379> bgsave
Background saving started

大致的执行流程是:

  • 创建一个子进程
  • 子进程执行SAVE命令,创建新的RDB文件
  • 当子进程完成新的RDB文件创建之后,会通知Redis服务器进程(新的RDB文件创建完成)
  • Redis服务器使用新的RDB文件替换旧的RDB文件

在这里插入图片描述

2.3、SAVE选项

  其实用户除了使用上述两种手动创建RDB文件的方式之外,还能通过设置SAVE选项,让Redis服务器在满足指定条件时自动执行BGSAVE命令,SAVE命令选项接收 seconds changes 两个参数,语法如下:

save <seconds> <changes>
  • seconds :指定触发持久化操作所需时长
  • changes :指定触发持久化操作所需的修改次数

  简单来说,如果Redis服务器在 seconds 秒之内,它包含的数据库总共执行了至少 changes 次修改,那么Redis服务器就自动执行一次BGSAVE命令,比如:

save 30 1000

  就是Redis服务器在30秒内至少执行了1000次修改,那么就会自动执行BGSAVE命令。实际Redis服务器是支持同时使用多个save选项的,我们可以在配置文件中找到默认的配置:

save 900 1
save 300 10
save 60 10000

当以下任意一个条件被满足是,服务器就会执行一次BGSAVE命令

  • 在900s(15分钟)之内,服务器对数据库执行了至少1次修改
  • 在300s(5分钟)之内,服务器对数据库执行了至少10次修改
  • 在60s(1分钟)之内,服务器对数据库执行了至少10000次修改

2.4、RDB文件结构

  通过下面的图,我们了解下RDB文件结构。

在这里插入图片描述

  • RDB文件表示符 :文件最开头的部分为RDB文件表示符,内容为“REDIS”这5个字符
  • 版本号 :RDB文件表示符之后的4个字符长度的数字
  • 设备附加信息 :记录生成RDB文件的Redis服务器及其所在平台的信息(如服务器版本、创建RDB的时间戳等)
  • 数据库数据 :记录Redis服务器存储的0个或任意多个数据库的数据,一般从0号数据库开始排列
  • Lua脚本缓存 :如果开启了复制功能,服务器将在RDB文件的Lua脚本缓存部分报错所有已被缓存的Lua脚本
  • EOF :标识RDB正文内容的末尾
  • CRC64校验和 :64位整数表示的CRC校验和,用来检查RDB文件是否出错或者损坏

2.5、RDB文件载入

  RDB文件载入的流程图如下:
在这里插入图片描述
  总的来说,无论用户使用哪种方式,如果遇到停机时,服务器丢失的数据量取决于创建RDB文件的时间间隔:间隔越长,停机丢失的数据就越多。所以RDB持久更像是一种备份手段而非一种普通的数据持久化手段,比如离线备份。为了解决可能丢失大量数据这一问题,所以推出了我们即将介绍的AOF持久化模式。

三、AOF持久化

  与RDB这种全量式持久化不同,AOF提供的是增量式持久化功能,核心原理是:服务器每次执行完写命令后,都会以协议文本的方式降被执行的命令追加到AOF文件的末尾。当服务器在停机后,只要重新执行AOF中保存的Redis命令,就可以将数据库恢复到停机之前的状态。

3.1、开启AOF功能

  用户可以通过服务器的appendonly选项来决定是否打开AOF持久化功能

appendonly <value>
  • appendonly yes :开启AOF持久化功能
  • appendonly no :关闭AOF持久化功能

  如果开启了AOF持久化功能,Redis服务器在默认情况下将创建一个名为 appendonly.aof 的文件作为AOF文件

3.2、配置AOF文件的冲洗频率

  当程序通过系统对文件进行写入时,系统并不会直接将数据写入硬盘,而是会将数据写入位于内存的缓冲区中,等到数据达到某些写入条件或者达到某个时限,系统才会将缓冲区的数据刷到硬盘中,从而提高程序的性能,但是也会给程序的写入操作带来不确定性。所以AOF就想用户提供了appendfsync 选项,用来控制系统冲洗AOF文件的频率,语法如下:

appendfsync <value>

appendfsync 的选项有:always、everysec、no 3个值,代表的意义分别如下:

  • always :每执行一个写命令,就对AOF文件执行一次冲洗操作
  • everysec :每隔1s,就对AOF文件执行一次冲洗操作
  • no :不主动对AOF文件进行冲洗操作,由操作系统决定何时对AOF进行冲洗

  Redis使用 everysec 作为 appendfsync 选项的默认值,所以没有明确的需求,尽量不要去修改这个选项的值。

3.3、AOF重写

  随着服务器不断运行,被执行的命令变得越来越多,那么记录这些命令的AOF文件就变成越来越大,假设对同一个键做了很多的修改操作,那么AOF文件中就会出现很多的冗余命令,比如:

127.0.0.1:6379> set fruit apple
OK
127.0.0.1:6379> set fruit orange
OK
127.0.0.1:6379> set fruit banana
OK
127.0.0.1:6379> sadd set v1
(integer) 1
127.0.0.1:6379> sadd set v2
(integer) 1
127.0.0.1:6379> sadd set v3
(integer) 1
127.0.0.1:6379> srem set v3
(integer) 1
127.0.0.1:6379> sadd set v4
(integer) 1

  实际上这些命令对数据库的最终修改效果可以简化为:

set fruit banana
sadd set v1 v2 v4

  这就是我们要提到的Redis提供的AOF重写功能,该功能能够生成一个全新的AOF文件,并且文件中只包含恢复当前数据库所需的尽可能少的命令。

3.3.1、BGREWRITEAOF命令(手动)

  用户可以通过执行BGREWRITEAOF 命令来显示地触发AOF重写,该命令是一个异步命令,Redis服务器接收到该命令之后会创建一个子进程,由它扫描整个数据库并生成新的AOF文件,当新的AOF文件生成完毕,子进程就会退出并通知Redis,然后Redis服务器就会使用新的AOF文件替代原来的AOF文件,完成重写操作。这个过程和我们之前RDB异步持久化差不多。不懂的可以看本文的2.2章节

BGREWRITEAOF
  • 如果发送BGREWRITEAOF 时,服务器在创建RDB文件,那么AOF重写操作会延到RDB文件创建完毕之后
  • 如果发送BGREWRITEAOF 时,已经在做重写操作,那么就会报错,提示AOF重写操作已经在处理了

3.3.2、AOF重写配置选项(自动)

  除了手动执行BGREWRITEAOF 命令创建AOF文件之外,还可以通过设置一下两个配置选项让redis自动触发BGREWRITEAOF 命令。

auto-aof-rewrite-percentage 100    #文件体积增大100%就自动重写
auto-aof-rewrite-min-size 64mb     #文件体积小于64mb不会重写
  • auto-aof-rewrite-min-size:设置触发自动重写AOF文件所需的最小的文件大小
  • auto-aof-rewrite-percentage:设置触发自动重写AOF文件所需要的文件大小增大的比例

四、RDB-AOF混合持久化

4.1、RDB和AOF的优劣

  上面我们介绍了Redis的两种持久化方式

  • RDB持久化,生成的RDB文件比较小,使用RDB文件进行恢复时速度非常快,但是RDB的全量式持久化模式可能会让服务器丢失大量数据
  • AOF持久化,存储的是协议文本,文件会比较大,并且使用AOF文件进行恢复时相对较慢(通过执行AOF文件中的命令),但是AOF持久化丢失的数据可以控制在1秒内

4.2、开启RDB-AOF混合持久化

  从Redis4.0开始引入了RDB-AOF混合持久化模式,这种模式还是基于AOF模式构建的,需要的两个条件是:

  • 开启了AOF持久化功能
  • 设置 aof-use-rdb-preamble yes

  满足这两个条件后,如果Redis在执行AOF重写操作时(上面介绍过),就会像执行BGSAVE命令那样,根据数据库当前的状态生成相应的RDB数据,并且将这个数据写入到新建的AOF文件中,那些在重写之后的命令,则会继续以协议文本的方式追加到AOF文件的末尾,也就是说,我们的服务器生成的AOF文件由两部分组成,最前面是RDB格式的数据,后面则是AOF格式的数据。

4.3、RDB-AOF混合持久化文件载入

  开启了RDB-AOF混合持久化模式的Redis服务器启动并载入AOF文件时,它会检查AOF文件的开头是否包含RDB格式的内容:

  • 如果包含,那么就会先载入开头的RDB数据,然后在载入之后的AOF数据
  • 如果不包含,那么就直接载入AOF数据

大致的流程图如下:

在这里插入图片描述

结语

  从Redis4.0之后我们应该优先使用RDB-AOF混合持久化,如果是Redis4.0之前的版本,RDB更像是数据备份,AOF更接近数据持久化,可以优先使用AOF持久化,并将RDB当做辅助(比如手动)数据备份手段。

相关文章:

  • 如何做网站内链/百度推广关键词
  • 怎么用vs做动态网站/上海网站设计公司
  • o2o网站建设方案讲解/seo优化软件大全
  • wordpress子主题修改/it培训学校it培训机构
  • 广西建设/优化网站关键词的技巧
  • 在线做雅思真题网站/站长工具域名解析
  • 快解析远程访问解决方案——安全稳定,部署简单
  • 三万秃发人群撑起一个IPO,大麦植发能成功上市吗?
  • Vue模板语法(一)
  • 鉴源论坛 · 观通丨轨交系统安全性设计
  • [ECE]模拟试题-5
  • ②【Spring】一文精通:IOC - 基于XML方式管理Bean
  • Android Studio 阅读 frameworks/base 下的代码
  • 不确定性量化 (UQ) 可以显著提高预测准确性,在不确定的世界中获得最佳结果昆士兰大学Mike McKerns-中国学者网
  • 【ESP 保姆级教程】玩转emqx篇 ——初识emqx
  • 前端学习记录-Javascript
  • nnUNet 训练 AMOS22数据集 Task216(抽丝剥茧指令+原理篇)
  • JSPmvc