持久化:将内存中的数据保存到硬盘中,常用的持久化方式有快照和写日志
- 快照:MySQL Dump、Redis RDB
- 写日志:MySQL Binlog、Hbase HLog、Redis AOF
Redis官方提供了两种不同的持久化方法来将数据存储到硬盘里面分别是:
持久化:将数据从内存保存到硬盘中
- 快照(Snapshot):保存某一时刻的数据状态
- AOF (Append Only File)只追加日志文件:将redis的所有写入命令记录到日志文件中
快照
特点:
这种方式可以将某一时刻的所有数据都写入硬盘中,这是redis默认的持久化方式,保存的文件以 .rdb 形式结尾,因此也称为 rdb 方式
快照生成方式:
- 客户端方式:BGSAVE 和 SAVE 命令
- 服务端配置自动触发
BGSAVE:客户端可以使用BGSAVE命令来创建一个快照,当接受到客户端的BGSAVE命令时,redis会fork来创建一个子进程,然后子进程负责将快照写入磁盘中,而父进程则继续处理命令请求
- 文件策略:如果存在老的 RDB 文件,新替换老
- 时间复杂度:O(n)
fork:当一个进程创建子进程时,底层的操作系统会创建该进程的一个副本,在类unix系统中创建子进程的操作会进行优化;在开始的时候父子进程共享相同内存,直到父进程或子进程对内存进行了写操作后,对被写入的内存的共享才会结束
SAVE:客户端调用SAVE命令来创建一个快照,接收到SAVE命令的redis服务器在创建快照完毕之前不再响应任何其他的命令(redis服务端会被阻塞)
- 文件策略:如果存在老的 RDB 文件,新替换老
- 时间复杂度:O(n)
服务端配置满足条件触发:
- 如果用户在redis.conf中设置了save配置选项,redis会在save选项条件满足之后自动触发一次BGSAVE命令,如果设置多个save配置选项,当任意一个save配置选项条件满足,redis也会触发一次BGSAVE命令
- 服务端接受客户端 shutdown 命令会触发一个 save 命令
- 全量复制(分布式)
- debug reload
- 默认开启:
```bash
save seconds changes
save 900 1 # 15min 一次修改 save 300 10 # 5min 10次修改 save 60 10000 # 1min 10000次修改
dbfilename dump-${port}.rdb dir /var/redis stop-writes-on-bgsave-error yes #bgsave出错则停止写入 rdbcompression yes #进行压缩 rdbchecksum yes
<a name="FBLDs"></a>
#### AOF
特点:<br />![](https://cdn.nlark.com/yuque/0/2020/png/750131/1606885769824-3b84b2c1-e5ce-4545-814c-315a95949dd2.png#align=left&display=inline&height=232&margin=%5Bobject%20Object%5D&originHeight=232&originWidth=885&size=0&status=done&style=none&width=885)<br />AOF:这种方式可以将客户端执行的**写命令**记录到日志文件中,AOF持久化会将被执行的写命令写到AOF的文件末尾,以此来记录数据发生的变化,因此只需要redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复AOF文件的记录的数据集
开启AOF持久化:在redis的默认配置中,AOF持久化机制是没有开启的,需要在配置中开启
> 修改 redis.conf 开启AOF持久化:
> - 开启持久化:appendonly yes
> - 指定生成文件名称:appendfilename "appendonly.aof"
> - 文件位置和快照位于同一位置:dir /var
>
日志写入频率:
> - appendfsync always:谨慎使用
> - appendfsync everysec:推荐
> - appendfsync no:不推荐
日志频率说明:<br />1、always:每个redis**写命令**都要同步写入硬盘,严重降低redis速度
> - 优点:always选项会将每个redis写命令同步写入硬盘,能够将发生系统崩溃时出现的数据丢失减少到最少
> - 缺点:这种同步策略需要对硬盘进行大量的写入操作,会受到硬盘性能的限制,转盘式硬盘在这种频率下200左右个命令/s,固态硬盘(SSD)几百万个命令/s【注意:在always这种不断写入少量数据的做法可能导致SSD产生严重的写入放大问题,从而降低SSD的使用寿命】
2、everysec:每秒执行一次同步显示的将多个写命令同步到磁盘【建议,性能影响小,数据丢失小】<br />3、no:由操作系统决定何时同步
> - 优点:不会影响性能
> - 缺点:
> - 当系统崩溃时,丢失的数据不确定
> - 当用户硬盘处理写入速度不够快时,当缓冲区被等待写入硬盘数据填满时,redis会处于阻塞状态,导致redis处理命令请求的速度变慢
AOF 文件的重写:
- AOF 带来的问题:持久化文件会变得庞大,如调用incr test 100次,文件中必须保存全部的100条命令,而需要恢复数据库保存一条 set test 100就够了,为了压缩 aof 的持久化文件,Redis 提供了AOF重写机制
- AOF 重写:在一定程度上减小 AOF 文件的体积
触发 AOF 重写的方式:
- 客户端命令:执行 BGREWRITEAOF 命令,不会阻塞redis服务
- 服务端配置:配置 redis.conf 中的 auto-aof-rewrite-percentage 选项和 auto-aof-rewrite-min-size
```bash
auto-aof-rewrite-percentage 100 # AOF文件增长率
auto-aof-rewrite-min-size 64mb # AOF文件第一次触发重写的大小
// 即第一次 64mb 重写,重写后假如为 30mb
// 设置为100%,即第二次重写为 30*2=60mb时重写
// 假设重写后为40mb,则第三次重写为80mb,以此类推...
# 统计
aof_current_size:AOF文件当前大小(单位:字节)
aof_base_size:AOF文件上次启动和重写的大小(单位:字节)
上述配置,如果启用AOF持久化时,那么当AOF文件体积大于64mb且AOF文件的体积比上一次重写之后体积大了至少一倍(100%)时,会自动触发,如果重写过于频繁,那么用户可以考虑将auto-aof-rewrite-percentage设置更大
AOF 重写原理:重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写写了一个新的aof文件,替换了原有的文件,这点和快照类似
- redis调用fork产生子进程,子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
- 父进程继续处理client请求,除了把写命令写入到原来的aof中,同时把收到的写命令缓存起来,这样就能保证如果子进程重写失败的话并不会出问题
- 当子进程把快照内容以命令方式写到临时文件后,子进程发信号通知父进程,然后父进程把缓存的写命令也写入到临时文件
- 现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加
AOF 完整配置:
appendonly yes #开启aof
appendfilename "appendonly-${port}.aof" #aof文件命名
appendfsync everysec #日志频率
dir /var/redis #日志文件保存位置
no-appendfsync-on-rewrite yes #在重写时不调用fsync()操作,此时Redis的持久化策略相当于appendfsync none
auto-aof-rewrite-percentage 100 #增长率
auto-aof-rewrite-min-size 64mb #发生第一次重写的aof文件日志大小
AOF 修复:redis-check-aof —fix
其他设置:
- aof-load-truncated:在Redis节点启动的时候,如果发现AOF文件已经损坏了,其处理逻辑与该参数的设置有关,若为yes,则会忽略掉错误,尽可能加载较多的数据,若为no,则会直接报错退出。默认为yes。需要注意的是,该参数只适用于Redis启动阶段,如果在Redis运行过程中,发现AOF文件corrupted,Redis会直接报错退出。
- aof-use-rdb-preamble:是否启用Redis 4.x提供的AOF+RDB的混合持久化方案,若为yes,在重写AOF文件时,Redis会将数据以RDB的格式作为AOF文件的开始部分。在重写之后,Redis会继续以AOF格式持久化写入操作。默认值为no
总结
RDB 和 AOF 对比:
命令 | RDB | AOF |
---|---|---|
启动优先级 | 低 | 高 |
体积 | 小 | 大 |
恢复速度 | 快 | 慢 |
数据安全性 | 丢数据 | 根据策略决定 |
轻重 | 重量级 | 轻量级 |
RDB 最佳策略:
- 主从模式,主关从开
- 集中管理
AOF 最佳策略:
- 开:缓存和存储
- AOF 重写集中管理
- everysec
最佳策略:
- 小分片
- 缓存或者存储
- 监控(硬盘、内存、负载)
优化:
硬盘优化:
AOF 追加阻塞:
AOF 阻塞定位:
两种持久化方案既可以同时使用(aof),又可以单独使用,在某种情况下也可以都不使用,具体用哪种持久化方案取决于用户的数据和应用;
无论使用AOF还是快照机制持久化,将数据持久化到硬盘都是很有必要的,除了持久化外,用户还应该对持久化的文件进行备份,最好备份在多个不同地方