Redis 持久化详解

一、简介

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

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

二、RDB持久化

  RDB持久化是Redis默认使用的持久化功能该功能可以创建出一个经过压缩的二进制文件它包含了服务器在各个数据库中存储的键值对数据等信息。RDB持久化产生的文件都以 .rdb 后缀结尾其中 rdb 代表Redis DataBaseRedis数据库。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命令

  • 在900s15分钟之内服务器对数据库执行了至少1次修改
  • 在300s5分钟之内服务器对数据库执行了至少10次修改
  • 在60s1分钟之内服务器对数据库执行了至少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当做辅助比如手动数据备份手段。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: redis

“Redis 持久化详解” 的相关文章