持久化的作用
什么是持久化
redis所有数据保存在内存中,对数据的更新将异步地保存到磁盘上
持久化的实现方式
快照,某时某点的完整数据备份
写日志,数据库任何更新操作写日志
RDB
什么是RDB
触发机制-主要的三种方式
save(同步)
生成文件策略,如果存在老的RDB文件,新替换老,会先生成一个临时文件,然后替换,时间复杂度O(n)
bgsave(异步)
bgsave的fork过程通常是非常快的,但还是会阻塞redis,阻塞发生在fork
生成文件策略,如果存在老的RDB文件,新替换老,会先生成一个临时文件,然后替换,时间复杂度O(n)
save和bgsave的比较
命令 | save | bgsave |
---|---|---|
IO类型 | 同步 | 异步 |
阻塞 | 是 | 是(阻塞发生在fork) |
复杂度 | O(n) | O(n) |
优点 | 不会消耗额外内存 | 不阻塞客户端命令 |
缺点 | 阻塞客户端命令 | 需要fork,消耗内存 |
自动
满足任何一个条件,
配置 | seconds | changes |
---|---|---|
save | 900 | 1 |
save | 300 | 10 |
save | 60 | 10000 |
配置
配置 | 说明 |
---|---|
save 900 1 | |
save 300 10 | |
save 60 10000 | 对应上面自动方式的三个条件 |
dbfilename dump.rdb | rdb文件叫什么名字 |
dir ./ | rdb、aof、日志文件存储位置 |
stop-writes-on-bgsave-error yes | 保存rdb文件出错是否停止写 |
rdbcompression yes | rdb文件是否采用压缩的格式 |
rdbchecksum yes | 是否对rdb进行校验 |
最佳配置
关闭自动生成
配置 | 说明 |
---|---|
dbfilename dump-${port}.rdb | rdb文件叫什么名字 |
dir /bigdiskpath | rdb、aof、日志文件存储位置 |
stop-writes-on-bgsave-error yes | 保存rdb文件出错停止写 |
rdbcompression yes | rdb文件采用压缩的格式 |
rdbchecksum yes | 对rdb进行校验 |
触发机制-不容忽略的方式
全量复制
debug reload
shutdown
AOF
RDB现存问题
- 耗时、耗性能
O(n)数据,耗时
fork()消耗内存,虽然使用copy-on-write策略
Disk I/O,IO性能 - 不可控、丢失数据
时间戳 | save |
---|---|
T1 | 执行多个写命令 |
T2 | 满足RDB自动创建的条件 |
T3 | 再次执行多个写命令 |
T4 | 宕机 |
则T3 数据丢失
什么是AOF
用两张图分别看下创建AOF、和从AOF中恢复数据
AOF三种策略
always
everysec
no
三种策略比较
策略 | always | everysec | no |
---|---|---|---|
优点 | 不会丢失数据 | 每秒一次fsync,丢一秒数据 | 不用管 |
缺点 | IO开销较大,一般的sata盘只有几百TPS | 丢一秒数据 | 不可控 |
AOF重写
AOF策略可以将每条命令都写入AOF文件中,随着命令持续写入、时间的推移、或者并发量增大,AOF会逐渐增大,恢复的话,会非常慢,随着文件无线增大,无论是磁盘管理,还是写入文件速度,都会有一定影响,所以提供了AOF策略来解决这个功能
AOF作用
AOF重写,就是把过期的、没有用的、重复的、一些可以优化的命令进行化简成一个小的AOF文件,来达到如下目的
- 减少磁盘占用量
- 加速恢复速度
AOF重写实现两种方式
bgrewriteaof命令
aof重写配置
首先看下配置
配置名 | 含义 |
---|---|
auto-aof-rewrite-min-size | AOF文件重写需要的尺寸 |
auto-aof-rewrite-percentage | AOF文件增长率 |
首先看下统计配置
统计名 | 含义 |
---|---|
aof_current_size | AOF当前尺寸(单位,字节) |
aof_base_size | AOF上次启动和重写的尺寸(单位,字节) |
自动触发机制
aof_current_size > auto-aof-rewrite-min-size
(aof_current_size - aof_base_size) / aof_base_size > auto-aof-rewrite-percentage
同时满足,会触发
AOF重写流程
执行bgrewriteaof命令的时候,如果当前有进程正在执行AOF重写,那么直接返回;如果有进程正在执行bgsave,那么等待bgsave执行完毕再执行AOF重写。
Redis主进程会fork一个子进程执行AOF重写,开销和RDB重写一样。
AOF重写过程中,不影响Redis原有的AOF过程,包括写消息到AOF缓存以及同步AOF缓存中的数据到硬盘。
AOF重写过程中,主进程收到的写操作还会将命令写到AOF重写缓冲区,注意和AOF缓冲区区分开。
由于AOF重写过程中原AOF文件还在陆续写入数据,所以AOF重写子进程只会拿到fork子进程时的AOF文件进行重写。
子进程拿到原AOF文件中的数据写道一个临时的AOF文件中。
子进程完成AOF重写后会发消息给主进程,主进程会把AOF重写缓冲区中的数据写道AOF缓冲区,并且用新的AOF文件替换旧的AOF文件。
配置
appendonly yes
appendfilename “appendonly-${port}.aof”
appendfsync everysec
dir /bigdiskpath
no-appendfsync-on-rewrite yes
auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage 100
RDB和AOF的抉择
RDB和AOF比较
命令 | RDB | AOF |
---|---|---|
启动优先级 | 低 | 高 |
体积 | 小 | 大 |
恢复速度 | 快 | 慢 |
数据安全性 | 丢数据 | 根据策略决定 |
轻重 | 重 | 轻 |
RDB最佳策略
- 建议关闭RDB
无论是Redis主节点,还是从节点,都建议关掉RDB。但是关掉不是绝对的,主从复制时还是会借助RDB。 - 用作数据备份
RDB虽然是很重的操作,但是对数据备份很有作用。文件大小比较小,可以按天或按小时进行数据备份。 - 主从,从开?
在极个别的场景下,需要在从节点开RDB,可以再本地保存这样子的一个历史的RDB文件。虽然从节点不进行读写,但是Redis往往单机多部署,由于RDB是个很重的操作,所以还是会对CPU、硬盘和内存造成一定影响。根据实际需求进行设定。
AOF最佳策略
- 建议开启AOF
如果Redis数据只是用作数据源的缓存,并且缓存丢失后从数据源重新加载不会对数据源造成太大压力,这种情况下。AOF可以关。 - AOF重写集中管理
单机多部署情况下,发生大量fork可能会内存爆满。 - everysec
建议采用每秒刷盘策略
最佳策略
- 小分片
使用maxmemary对Redis最大内存进行规划。 - 缓存和存储
根据缓存和存储的特性来决定使用哪种策略 - 监控(硬盘、内存、负载、网络)
- 足够的内存
不要把就机器全部的内存规划给Redis。不然会出很多问题。像客户端缓冲区等,不受maxmemary限制。规划不当可能会产生SWAP、OOM等问题。