Redis数据持久化机制
1.数据库结构
一个单机Redis服务器默认有16个数据库,这个数量是可以配置的,每个数据库都由一个redis.h和redisDB表示,记录了键空间、键过期时间、阻塞状态等
2 RDB持久化
RDB持久化(快照持久化)将内存中的数据生成快照保存到磁盘里面,文件后缀是.rdb,是一个经过压缩的二进制文件,Redis重启的时候读取快照文件恢复数据
这是一个单文件全量数据,适合数据库的容灾备份,1G的快照文件载入内存的时间大概是20s
2.1 RDB的创建和载入
2.1.1 手动保存
- SAVE命令:是一个同步式命令,它会阻塞Redis服务器进程,直到RDB文件创建完成为止,期间服务器不能处理任何其他命令请求
- BGSAVE:异步命令,开启一个子进程来创建RDB文件,父进程继续处理客户命令
2.1.2 自动保存
满足一些条件的时候会自动触发BGSAVE方式进行保存(以下三个条件中的一个)
- 服务器在 900 秒之内,对数据库进行了至少 1 次修改。
- 服务器在 300 秒之内,对数据库进行了至少 10 次修改。
- 服务器在 60 秒之内,对数据库进行了至少 10000 次修改。
Redis每100毫秒执行一次serverCron函数,它的一项任务就是检查当前是否满足自动保存的条件
2.1.3 启动自动载入
Redis没有运行期间载入本地备份的机制,从逻辑上来说也没有必要,只是在重启的时候会从本地载入数据
2.2 RDB文件结构
2.2.1 存储路径
文件存储的名称(默认dump.rdb)和路径都是可以设置的,不是很重要,不细说
2.2.2 文件内容
大体可以分为两个部分
databases:包含着零个或者任意多个数据库,以及各个数据库的键值对数据
- SELECTDB:长度为一个字节的常量,告诉用户程序接下来要读取的是一个 db_number
- db_number:保存着一个数据库编号。当程序读到 db_number 时,服务器会立即调用 SELECT 命令切换到对应编号的数据库
- key_value_pairs:保存了数据库中的所有键值对数据,包括带过期时间和不带过期时间两种类型的键值对
- 存储5组数据:过期标记、过期时间、类型、key、value,如果是不带过期时间的键值对则没有前两组数据
其他:包含Redis版本、主机架构、内存配置等源数据信息
2.3 RDB常用配置项
- save m n:bgsave自动触发条件
- stop-writes-on-bgsave-error yes:当BGSAVE命令出现错误是,Redis是否停止执行写命令
- rdbcompression yes:是否开启 RDB 文件压缩。
- rdbchecksum yes:是否开启 RDB 文件的校验,在写入文件和读取文件时都起作用。关闭 checksum 在写入文件和启动文件时大约能带来 10% 的性能提升,但是数据损坏时无法发现。
- dbfilename dump.rdb:设置 RDB 的文件名。
- dir ./:设置 RDB 文件和 AOF 文件所在目录。
3 AOF持久化
AOF 会把 Redis 服务器每次执行的写命令记录到一个日志文件中,当服务器重启时再次执行 AOF 文件中的命令来恢复数据,且AOF的优先级要高于RDB的,如果开启了AOF则不会使用RDB方式进行恢复
3.1 AOF创建
1 | <!--AOF 默认是关闭的,通过这个命令启动--> |
3.2 工作原理
将对Redis服务器的所有写命令都自动记录到AOF文件中
- 命令追加(append):将 Redis 执行的写命令追加到 AOF 的缓冲区 aof_buf
- 文件写入(write)和文件同步(fsync):AOF 根据对应的策略将 aof_buf 的数据同步到硬盘
- write:操作系统会将数据先写入到内存缓冲区中,当缓冲区被填满或者超过了指定限制之后才真正将数据写入到磁盘里
- fsync:write会有一个问题,如果刺痛宕机则会丢失缓存中的数据,为此同时提供了fsync同步函数,Redis提供三种缓存同步机制
- appendfsync always:每执行一次命令保存一次
- appendfsync no:不保存,有操作系统负责,通常是30s
- appendfsync everysec:每秒钟保存一次(前两种策略的折中,Redis默认规则)
- 文件重写(rewrite):定期对 AOF 进行重写,从而实现对写命令的压缩。
- AOF 文件重写指的是把 Redis 进程内的数据转化为写命令,同步到新的 AOF 文件中,然后使用新的 AOF 文件覆盖旧的 AOF 文件,这个过程不对旧的 AOF 文件的进行任何读写操作。
- 压缩原理:过期的数据不再写入AOF文件、无效命令(重复对key赋值)不再写入文件、多条命令被合并为单个
3.3 AOF常用配置项
- appendonly no:是否开启 AOF 持久化功能
- appendfilename “appendonly.aof”:AOF 文件的名称
- dir ./:RDB 文件和 AOF 文件所在目录
- appendfsync everysec:fsync 持久化策略
- no-appendfsync-on-rewrite no:重写 AOF 文件期间是否禁止 fsync 操作。如果开启该选项,可以减轻文件重写时 CPU 和磁盘的负载(尤其是磁盘),但是可能会丢失 AOF 重写期间的数据,需要在负载和安全性之间进行平衡
- auto-aof-rewrite-percentage 100:AOF 文件重写触发条件之一
- auto-aof-rewrite-min-size 64mb:AOF 文件重写触发条件之一
- aof-load-truncated yes:如果 AOF 文件结尾损坏,Redis 服务器在启动时是否仍载入 AOF 文件
4 数据恢复机制
- AOF优先级高于RDB(AOF的精度高于RDB)
- AOF开启的时候,即使AOF文件不存在,Redis也不会尝试使用RDB来进行数据恢复(这个时候应该是认为Redis在上次关闭时内存中没有数据)
5 RDB和AOF对比
| 机制 | RDB | AOF |
|---|---|---|
| 启动优先级 | 低 | 高 |
| 磁盘占用 | 小 | 大 |
| 数据还原速度 | 快 | 慢 |
| 数据安全性 | 容易丢失 | 正常配置都会相对高 |
| 操作轻重级别 | 重 | 轻 |
5.1 RDB优缺点
优点
- 文件结构紧凑,保存了某个时间节点上的所有数据,且磁盘占用小,适合做数据的备份和灾难恢复
- 数据备份时只要开启一个子进程来完成数据的写入操作,对父进程不受到影响
- 数据恢复时比AOF更快
缺点
- 数据的保存是一个重量级的操作,可能需要几分钟的时间,而且默认的配置是一个小时保存一次,所以可能会丢失几分钟或者更多的数据
- Redis数据集较大时,子进程要完成快照比较耗费CPU和时间
5.2 AOF的优缺点
优点
- 数据完整性更高、秒级的数据丢失
- 文件是进行命令追加的命令文件,已Redis协议格式保存,可读,适合误删紧急恢复(从记录中找出被误删数据的写入命令执行)
缺点
- 文件体积更大,恢复速度更慢
6 混合持久化
- Redis 4.0 版本提供了一套基于 AOF-RDB 的混合持久化机制,保留了两种持久化机制的优点
- 基本的思路是,使用RDB来定时的对数据进行备份,在备份过程(或者是备份间隔)的时间的数据通过AOF来备份,即大部分的数据是通过RDB来进行备份的,最后小部分时间片段的数据通过AOF来进行备份
- 这样重写的 AOF 文件由两部份组成,一部分是 RDB 格式的头部数据,另一部分是 AOF 格式的尾部指令。
7 不同场景的策略选择
- 数据库缓存:这个时候其实Redis服务器出现意外宕机数据丢失也无所谓,数据库中还维护这完整的数据,所以为了性能最大化,可以将所有持久化策略关闭
- 单机环境:如果可以接受十几分钟或者一个小时的数据丢失,那么使用RDB是一个很好的选择;如果只能接受秒级别的数据丢失,AOF更好一些
- 主从部署:大多数时候都会使用主从部署
- 这时候主节点可以完全关闭持久化,从节点关闭RDB开启AOF
- 定时对持久化文件进行备份
- 关闭AOF自动重写功能,手动添加定时任务,在Redis服务器压力小的时间节点上调用bgrewriteaof对持久化文件进行重写
- 主从结构下还要对数据进行持久化,是预防所有节点同时宕机
- 异地灾备:将持久化文件定时拷贝发送到远程机器进行存储
