前言
开启redis之旅
Redis的持久化
Redis是直接操作内存的,如果需要保存数据,需要把内存的数据持久化到硬盘上,否则一旦宕机则会丢失数据。而Redis提供了两种持久化的机制,也就是下面要说的RDB和AOF。
- 首先我们先看看持久化操作主流的方法
- 快照形式(MySQL Dump、Redis RDB)
我们取某一时刻数据的状态进行保存。 - 日志形式(MySQL Binlog、Hbase HLog、Redis AOF)
我们把我们操作的记录存到日志文件里,当我们需要恢复数据时在重新执行一遍。
- 快照形式(MySQL Dump、Redis RDB)
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
配置 | 秒 | 改变/ | 说明 |
---|---|---|---|
save | 900 | 1 | 如果900秒内有操作Redis 1次,就生成 |
save | 300 | 10 | 如果300秒内有操作Redis 10次,就生成 |
save | 60 | 10000 | 如果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-size AOF文件重写需要的尺寸(达到尺寸后开启重写) auto-aof-rewrite-percentage AOF文件增长率 当我们要触发重写需要满足下面两个条件
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