一文搞懂 Redis 的 持久化机制
Redis 支持的 持久化机制 有三种:- RDB(Redis DataBase)持久化- AOF(Append Only File)持久化- RDB-AOF 混合持久化RDB:- Redis 默认采用的持久化机制- 以 快照 的形式将进程数据持久化到硬盘中- 会生成一个经过 压缩 的二进制文件(文件后缀为 .rdb)- 文件内部存储了各个数据库的键值对数据AOF:- 目前 Redis 持久化 的
一文搞懂 Redis 的 持久化机制
Redis 支持的 持久化机制 有三种:
- RDB(Redis DataBase)持久化
- AOF(Append Only File)持久化
- RDB-AOF 混合持久化
1、RDB(Redis DataBase)
- Redis 默认采用的持久化机制
- 以 快照 的形式将进程数据持久化到硬盘中
- 会生成一个经过 压缩 的二进制文件(文件后缀为 .rdb)
- 文件内部存储了 各个数据库的 键值对数据
注:Redis 默认有 16 个数据库,分别是 DB0 ~ DB15
持久化的触发方式:
- 手动触发:通过 save / bgsave 命令 触发持久化操作
- 自动触发:通过配置选项,让服务器在满足指定条件时自动执行 bgsave 命令
注:RDB 保存的默认文件是 dump.rdb
save 与 bgsave 命令的比较
- save 命令 采用同步的方式 :使用 Redis 服务器进程 进行 “.rdb” 文件的创建,命令执行期间 Redis 服务器将一直处于阻塞状态
- bgsave 命令 采用异步的方式:使用 Redis 服务器进程 的 子进程进行 “.rdb” 文件的创建,只有在创建 子进程 时 Redis 服务器才会处于阻塞状态,创建完毕之后便脱离阻塞状态
注:由于 save 命令存在的阻塞问题,目前 save 命令 已被废弃
bgsave 命令的执行流程:
- 若父进程存在正在执行的子进程,直接返回
- fork 操作(创建子进程) 执行过程中,父进程进入阻塞状态
- fork 操作 完成后,父进程继续响应其他命令
- 创建 “.rdb” 文件,并存储 父进程内存中的数据
- 父进程 得到通知,以新的 “.rdb” 文件 替换旧的 “.rdb” 文件
bgsave 命令的原理:COW(Copy On Write)
- 在 Linux 操作系统中,可以通过 glibc库 中的 fork 函数 创建一个子进程,该进程与父进程完全相同,并且共享 父进程 的内存空间
- 当 父进程 或 子进程 需要修改内存中的数据时,会将对应的 page 进行复制,然后对副本进行修改
RDB 的优缺点:
- 优点:生成的二进制文件体积小,恢复数据的速度快
- 缺点:bgsave 命令每次执行时都会 创建子进程(属于重量级操作),资源消耗大
补充:由于 创建子进程 时,Redis 服务器进程 会阻塞一段时间,因而 RDB持久化 没办法做到实时的持久化。
2、AOF(Append Only File)
- 目前 Redis 持久化 的主流方式(解决了数据持久化的实时性)
- 以 独立日志 的方式,记录了每次写入的命令
- 生成一个 文本协议格式 的 文本文件(文件后缀为 “.aof”)
AOF 默认不开启,需要修改配置项来启动它:
appendonly yes # 启动 aof
appendfilename "appendonly.aof" # 设置文件名
注:AOF 保存的默认文件是 appendonly.aof
AOF 的工作流程:
- 命令写入(append)
- 文件同步(sync)
- 文件重写(rewrite)
- 重启加载(load)
补充:
AOF 以 文本协议格式 写入命令,如:
*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n
文本协议格式的优点:
- 良好的兼容性
- 避免二次处理的开销
- 可读性高,方便直接修改和处理
AOF 的 文件同步机制:
- 为了提高程序的写入性能,现代操作系统会把针对硬盘的多次写操作优化为一次写操作
- 当程序调用 write 对文件写入时,系统不会直接将数据写入硬盘,而是先将数据写入到 内存的数据缓存区 中;当 数据缓存区 写满时 或 达到一定的 时间周期 时,系统才会执行 flush 操作,将 数据缓存区 的全部数据 一次性写入硬盘
- 这种优化机制虽然提高了性能,但同时也给程序的写入操作带来了不确定性
- 当 内存掉电 而 还没进行 flush 操作 时,数据缓存区的数据会直接全部丢失
- 为了减小这种不确定性带来后果,Redis 向用户提供了 appendfsync 选项,用来控制系统 冲洗(flush) AOF文件 的频率
- appendfsync 基于 Linux 操作系统中 glibc库 中的 fsync函数,该函数可以将指定文件强制从数据缓冲区 冲洗 到硬盘上
补充:appendfsync 选项的取值 和 含义
取值 | 说明 |
---|---|
always | 每执行一个写入命令,就对 AOF文件 执行一次冲洗操作 在这种情况下,服务器在停机时最多丢失一个命令,但同时会大大降低服务器的性能 |
everysec | 每隔1秒,就对 AOF文件 执行一次冲洗操作 在这种情况下,服务器在停机时最多丢失1秒之内的命令,是一种兼顾性能和安全性的折中方案 |
no | 不主动对 AOF文件执行冲洗操作,由操作系统决定何时冲洗 在这种情况下,服务器在停机时将丢失最后一次冲洗后执行的命令,数据量取决于系统的冲洗频率 |
AOF 的优缺点:
-
优点:相较 RDB(一旦 内存掉电,存在于内存的数据全部丢失),AOF 丢失数据的量更小,而通过 everysec 选项,用户可以将数据丢失的时间窗口限制在1秒之内。
-
缺点:
- AOF文件 存储的是 协议格式文本,其体积 相较于 RDB 的二进制文件 大很多
- 当需要恢复较多数据时,使用 AOF文件 恢复的速度会比较慢(原因在于:需要重新执行每一条命令)
- AOF 在进行重写时也需要创建 子进程,当数据量较大时将占用较多资源,同时会导致服务器处于短暂阻塞状态
3、RDB-AOF 混合模式
-
基于 AOF 、结合 RDB 的优点 进行构建
-
执行 AOF 重写操作时
- 执行 bgsave 命令生成 RDB数据,并将其写入 AOF文件 中
- 对于重写之后执行的命令,则以 协议文本 的方式追加到 AOF文件 的末尾(即 RDB数据 之后)
-
混合模式拥有 AOF、RDB 两者的优点
- 服务器可以通过 AOF文件 包含的 RDB数据 来实现快速的数据恢复
- 服务器可以通过 AOF文件 包含的 AOF数据 来将丢失数据的时间窗口限制在1秒之内
更多推荐
所有评论(0)