Redis的持久化机制RDB和AOF

前言

开启redis之旅

Redis的持久化

Redis是直接操作内存的,如果需要保存数据,需要把内存的数据持久化到硬盘上,否则一旦宕机则会丢失数据。而Redis提供了两种持久化的机制,也就是下面要说的RDB和AOF。

  • 首先我们先看看持久化操作主流的方法
    • 快照形式(MySQL Dump、Redis RDB)
      我们取某一时刻数据的状态进行保存。
    • 日志形式(MySQL Binlog、Hbase HLog、Redis AOF)
      我们把我们操作的记录存到日志文件里,当我们需要恢复数据时在重新执行一遍。
RDB

RDB的原理就是在某一时刻我们去生成RDB文件,之后我们在Redis重启的时候去载入这个文件就可以了。原理图如下。

RDB触发机制

如何使Redis程序去执行复制文件呢

  • sava(同步)
  • bgsave(异步)
  • 自动(在某些情况会自动执行)

Redis在复制时会生成一个拷贝,然后等待复制完成之后拷贝文件将会覆盖之前生成的文件,这种模式也就是我们所知道的Copy-On-Write,但是随之而来的问题就是我每次拷贝都需要一个零时文件,所以在拷贝的时候是需要足够的空间的,当空间不够的时候就会拷贝失败

sava

执行save命令会阻塞Redis的其他操作,而去复制文件

由于Redis是单线程,所以这个命令基本是不用的,我们不能使用户去等待我们复制操作。

bgsave

执行bgsave时Redis会fork一个子进程去执行复制,这样不会影响到用户的操作。如下图。

这里有一个问题,虽然说bgsave是异步的,但是在fork的时候还是会阻塞Redis进程,所以当你系统在fork进程非常慢的时候,用户的操作同样会被阻塞住且fork会消耗额外的内存噢。

save 和 bgsave的比较

我们一般是使用bgsave,不过还是给出比较

自动生成RDB

上述都是我们自己手动执行命令去生成RDB文件,Redis为了方便我们操作我们可以在操作文件里配置自动生成的策略。
下面的配置是Redis默认的配置,生成策略是使用bgsave

配置改变/说明
save9001如果900秒内有操作Redis 1次,就生成
save30010如果300秒内有操作Redis 10次,就生成
save6010000如果60秒内有操作Redis 10000次,就生成

但是生成RDB文件的开销还是很大的,特别是如果数据量多的时候。Redis的默认配置生成策略有点太频繁了。所以我们基本不用,要用就把频率改小一点。

插入相关的配置 以及一般在生产中的配置和默认配置的对比

默认配置
#下面3条上面已经说明
save 900 1
save 300 10
save 60 10000
dbfilename dump.db #RDB文件名
dir ./ #RDB文件保存路径
stop-writes-on-bgsave-error yes#如果bgsave出现问题是否立刻停止写入
rdbcompression yes #RDB是否采用压缩格式存储
rdbchecksum yes #是否对RDB进行校验

最佳配置
#一般不使用下面的3条默认配置
#save 900 1
#save 300 10
#save 60 10000
dbfilename dump-${port}.rdb #一般使用port进行区分
dir /bigdiskpath #存在划分的文件系统或比较大的目录
stop-writes-on-bgsave-error yes #如果bgsave出现问题是否立刻停止写入
rdbcompression yes #RDB是否采用压缩格式存储
rdbchecksum yes #是否对RDB进行校验

Redis默认会触发RDB生成

很重要,在一些场景下Redis会自动触发RDB文件的生成!

  • 1 全量复制(后面会讲)
  • 2 debug reload(重启的时候)
  • 3 shutdown(关闭的时候)
RDB的缺点:


AOF触发机制

我们通过上面的介绍我们可以知道RDB是耗时且耗性能的,且无法保证数据的完整性,我们下面就看看AOF怎么能否解决这些问题。

原理

AOF的原理是我们把用户的操作都存到AOF文件中,之后如果宕机了的话我们把AOF文件重新执行一遍即可恢复数据。如下图所示

AOF的三种策略

在执行上面的操作中,Redis不是直接将命令写入到缓存中,而是先写入到缓存中,然后根据我们下面的三种策略去执行fsync命令把缓存的数据刷到文件中去。

  • always
    每次执行一条命令就执行一次fsync
  • everysec
    每秒执行一次fsync
  • no
    由操作系统决定什么时候执行

上面的三种策略最常用的就是everysec,如果使用always时,每一条命令都去执行一次fsync,这效率可想而知。如果使用no又不可控。所以我们就在性能和可靠性取中,可以知道everysec可能会丢失 1 秒的数据,这也是我们所能容忍的范围。

AOF的重写

AOF存在一个问题,随着我们写入的数据很多时,AOF文件会越来越大。所以Redis提供了AOF重写机制。总的来说就是压缩AOF文件,把重叠的数据转化成一个数据。

我们执行 
set hello word
set hello java
set hello redis
执行AOF重写之后这三条命令会转化回一个命令
set hello redis

AOF会把重复的,过期的数据优化掉,以减少硬盘的占用量加速恢复速度
那么如何让Redis执行AOF重写操作呢。

  • 1 使用bgrewriteaof命令
    bgrewriteaof的原理:
    在这里插入图片描述

  • 2 AOF重写配置
    下面是配置参数

    配置名含义
    auto-aof-rewrite-min-sizeAOF文件重写需要的尺寸(达到尺寸后开启重写)
    auto-aof-rewrite-percentageAOF文件增长率

    当我们要触发重写需要满足下面两个条件
    1 当前AOF文件大小 > AOF文件重写需要的尺寸(auto-aof-rewrite-min-size)
    2 当前AOF文件大小 - AOF上一次重写的大小 / AOF增长率(auto-aof-rewrite-percentage)

当然,在AOF重写的过程中,我们主线程会将在重写过程中的数据存储到aof_rewrite_buf中,等到AOF重写完之后将会追加到新的AOF文件里。

插入AOF功能相关的配置 以及一般在生产中的配置和默认配置的对比

appendonly yes #开启AOF功能 注意:默认是 no
appendfilename appendonly-${port}.aof #AOF文件位置
appendfsync everysec #上面说的三种策略
dir /bigdiskpath #存在划分的文件系统或比较大的目录
no-appendfsync-on-rewrite yes #在重写的时候是不追加到旧的AOF文件
auto-aof-rewrite-percentage 100#增长率(扩大一倍)
auto-aof-rewrite-min-size 64mb #最小尺寸

AOF和RDB的选择

AOF和RDB的比较


这里的启动优先级是指Redis会优先选择AOF策略。

AOF和RDB的最佳策略
  • RDB:
    • 1 我们一般不使用RDB方式,但是我们上面也提到了,RDB会有触发机制,所以是没办法完全关闭的。
    • 2 集中管理时
    • 3 主从模式的时候(后面章节会说明) 从节点使用
  • AOF:
    • 1 一般是使用AOF
    • 2 everysec
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值