§1 持久化方式
- RDB:内存快照
- AOF:增量写操作指令日志
对比
RDB | AOF | |
---|---|---|
默认开启 | √ | × |
数据规模 | 大 | - |
完整性一致性 | 低 | 高 |
保存效率 | 高于 AOF,大数据量时有性能损耗 | AOF 的复写基于 RDB |
恢复速度 | 快 | 慢 |
自动恢复 | √ | √ |
异常恢复 | /usr/local/bin/redis-check-dump --fix dump.rdb | /usr/local/bin/redis-check-aof --fix appendonly.aof |
恢复优先级 | 同时存在 AOF 时不生效(AOF有异常时生效) | 优先(因为通常相对更完整) |
默认进行 | √ | × |
空间占用 | 相对较少,但 fork 时 2 倍膨胀 | 相对较多 |
丢失 | 可能丢失最后一次(redis 挂了) | 极少,但同步策略为 always 时可能有性能压力 |
选择
- 推荐 同时启用
- 对完整性、可靠性要求有限,可以单独使用 RDB
- 不建议 单独使用 AOF,可能遇到不可恢复不可修复的 bug
- 作为纯内存缓存时,可以都不用(因为丢了从持久化层重写拉一份即可,不心疼)
最佳实践
- 同时使用 RDB、AOF
- RDB 作为兜底方案,只在从节点上使用(因为没有写操作所以不用 AOF),只保留
save 900 1
一条规则 - 尽量减少 AOF 重写的频率
auto-aof-rewrite-min-size 64mb
过小,可以设置为 GB 级别,比如auto-aof-rewrite-min-size 5gb
auto-aof-rewrite-percentage
根据测试情况调整为默认值(按重写前后 AOF 实际比例决定)
§2 RDB
特点
- 在指定时间内将内存中的数据集快照写入磁盘
- 恢复时,直接将文件读到内存
- 使用写时复制,是针对数据备份文件(默认 dump.rdb)的写时复制
- 默认开启
优点
适合大规模数据恢复
适合对完整性、一致性要求不高的场景
节省磁盘空间
恢复速度读快
缺点
fork 时,空间占用 2 倍膨胀,因为需要复制一份以完成写时复制
大数据量时会有性能损耗
因为是周期性持久化,可能丢失最后一次持久化到 redis 挂掉之间的数据
工作流程
- 创建 fork 子进程
- 将数据写入临时文件
- 持久化过程都结束后,用临时文件替换上一次 RDB 的持久化文件
配置
参考 中间件 | Redis - [安装 & 配置]
§2 AOF
特点
- append only file,以日志文件的形式增量保存写指令,AOF 文件只追加,不修改
- redis 重启时,会将 AOF 上的指令完整的执行一次以恢复
- 默认不开启,文件名
appendonly.aof
,路径为安装路径 - AOF 文件损坏时,可以通过
/usr/local/bin/redis-check-aof --fix appendonly.aof
进行恢复
优点
- 可靠性高,丢失数据概率第
- AOF 文件相当于用户写操作的日志,可以通过它处理误操作(用户的操作可追溯了)
缺点
- 占用空间更多
- 恢复速度更慢
- 同步策略为
always
时,存在性能压力 - 可能出现不能恢复与修复的 bug
工作流程
- 客户端请求的写指令追加到 AOF 缓冲区
- AOF 缓冲区根据 AOF 同步策略与磁盘中 AOF 文件进行同步
- 对 AOF 文件进行重写以压缩空间
- 自动重写:AOF 文件大小超过重写策略时触发
- 手动重写
- redis 重启时,完整的重载 AOF 文件中素有指令
同步策略
通过 redis.conf
中下面配置项配置
appendfsync everysec
- always
始终同步,所有写入操作会立即同步
数据完整性好,但性能略差 - everysec
每秒同步,宕机时,最后一秒数据可能丢失 - no
不主动同步,同步时机由操作系统控制
重写压缩
AOF 使用文件追加,文件会越来越大,满足重写压缩策略时,redis 会重写 AOF 文件以压缩体积
重写后的只保留可以恢复数据的 最小指令集
可以通过指令 bgrewriteaof
手动重写
重写压缩策略
重写压缩会有一定的性能开销,redis 会记录每次重写后文件大小,并需要同时满足下面条件
- 相对上次重写后文件,体积增大一定的比例(相对大小)
- 文件大小达到指定的阈值(绝对大小)
通过 redis.conf
中下面配置项配置
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
no-appendfsync-on-rewrite no
用于设置 AOF 文件重写过程中的用户请求 是否不与原 AOF 文件同步yes
时,用户请求只进入重写 AOF 文件时使用的缓冲区,不向磁盘中的原 AOF 文件同步
因此如果此时宕机,开始 AOF 文件重写后、宕机之前的用户指令可能丢失
但不会阻塞用户请求no
时,用户请求依然需要向原 AOF 文件同步
但会阻塞用户线程,否则新的 AOF 文件不能替换原文件(因为指令不是无缝衔接的)
auto-aof-rewrite-percentage 100
用于配置 AOF 文件重写比例
AOF 文件相对上次重写后,增长超过这个比例才可能重写auto-aof-rewrite-min-size 64mb
用于配置 AOF 文件重写阈值
AOF 文件大小需要超过这个值才可能重写
原理
- 通过写时复制
- 将 RDB 快照转为二进制,附着在新 AOF 的头部
- 替换原 AOF 文件
重写压缩流程
- 自动或
bgrewriteaof
触发重写- 判断当前是否有
bgsave
或bgrewriteaof
正在进行中 - 如果有,阻塞当前重写
- 如果没有,继续
- 判断当前是否有
- fork 子进程进行重写
- 遍历 redis 内存中数据到临时文件
- 新的客户端请求同时写入
aof_buf
缓冲区 和aof_rewrite_buf
重写缓冲区
可以保证原 AOF 文件完整(其实必须得同步原 AOF 文件才能真的保证)
可以保证新 AOF 文件生成期间新用户请求不会丢失
- 新的客户端请求同时写入
- 新 AOF 文件完成后
- 子进程通知主进程,主进程更新统计信息
- 主进程把
aof_rewrite_buf
重写缓冲区 的数据写入新 AOF 文件
- 新 AOF 文件覆盖旧的 AOF 文件
配置
参考 中间件 | Redis - [安装 & 配置]