持久化
通常我们认为持久化为: 重启进程/重启主机之后, 数据仍然存在不丢失
把数据存储在硬盘上 – 持久
把数据存储在内存中 – 不持久
Redis 持久化
redis 是一个内存数据库, 也就是说本身是不持久的(但是快[效率高]), 于是 Redis 提供了持久化机制 — RDB 和 AOF
二者都是对 Redis 数据的硬件备份, 区别在于
RDB 是定时备份, 二进制格式保存数据
AOF 是实时备份, 文本格式保存数据
RDB(Redis Database)
RDB 持久化是把当前进程数据生成快照保存到硬盘的过程, RDB 持久化的触发过程分为 手动触发和自动触发
RDB 触发机制
手动触发
程序员(人) 通过 redis 客户端, 执行特定命令 (save, bgsave) 来触发快照生成.
- sava 命令: Redis 主线程停止其他工作, 进行 RDB 过程 (会对 Redis 服务器造成阻塞[单线程模型])
- bgsave 命令: Redis 进程执行 fork 操作创建子进程, 子进程负责 RDB 持久化过程, 阻塞只发生在 fork 阶段, 不涉及长时间的阻塞 .
bgsave 命令的运行流程
- 执行 bgsave 命令, Redis 父进程会判定其他子进程是否正在执行 (RDB/AOF 子进程), 如果存在则直接返回
- 父进程 fork 一个子进程, fork 过程父进程阻塞
- 父进程 fork 完子进程后, bgsave 命令返回 “Background saving started” 信息, 父进程不再阻塞, 可以响应其他命令
- 子进程创建 RDB 文件, 根据 父进程内存 生成临时快照, 完成后对原有文件进行 替换
- RDB 文件替换完成后, 子进程 发送信号 给父进程, 通知父进程 RDB 操作完成, 父进程更新信息
自动触发
通过程序配置的一些设定, redis 依据某些条件自动触发 RDB 持久化操作.
- 配置文件中设置触发频率
"save m n "
对应 m 秒内数据集发生了 n 此变化, 就触发 RDB 持久化
- 使用
shutdown
命令关闭 Redis, 会执行 RDB 持久化 (service redis-server restart
命令也会触发) - Redis 进行主从复制时, 主节点会生成 RDB 快照, 传输给从节点. (此时也触发 RDB 持久化)
RDB 持久化的优缺点
- RDB 是二进制文件, 代表 Redis 在某个时刻的数据快照, 适用于备份, 全量复制等场景.
- RDB 机制 恢复数据速度远远快于 AOF 机制 (RDB 文件以二进制形式存储, AOF 文件以文本文件形式存储, 读 RDB 文件可以按照字节格式取出, 放到对应结构体/对象中, 读 AOF 文件需要进行一系列字符串切分操作 [耗时久 …])
- RDB 机制在两次生成快照之间, 实时数据可能会丢失(不正常关闭,第二次 快照生成失败)
- RDB 文件使用 特定二进制 格式保存, 不同版本兼容性有风险
AOF (Append Only File)
AOF 机制就是把用户的 每次操作 , 都记录到一个文件中, 当 Redis 重启的时候, 会读取这个 AOF 文件的内容(一堆操作), 来恢复数据 .
术语一点的说法:
以独立日志的方式记录每次写命令, 重启时重新执行 AOF 文件中的命令以达到恢复数据的目的 .
- AOF 机制默认关闭, 可通过修改配置文件来开启
- AOF 优先级高于 RDB, 当 aof 文件和 rdb 文件同时存在时,并且两个机制都启用时, rdb 文件会失效
对 redis.conf 文件进行修改
AOF 工作流程
- 所有写入的命令会追加到 缓冲区 (aof_buf) 中
- AOF 缓冲区根据对应的策略向硬盘做同步操作
- 随着 AOF 文件的越来越大, 定期对 AOF 文件进行重写,压缩
- Redis 重启时, 加载 AOF 文件进行数据恢复
AOF 缓冲区
缓冲区: AOF 机制会将用户操作/命令, 先写入到缓冲区, 积累一些后,再统一写入硬盘 AOF 文件末尾
- 写入缓冲区操作比写入硬盘操作要快
- 写入 AOF 文件末尾是顺序写入, 要比随机写入要快
缓冲区刷新频率 设置参数
aways : 命令写入缓冲区后直接刷新
everysec : 每秒由同步线程调用刷新操作
no : redis 线程不主动刷新, 由 OS 控制刷新频率
缓冲区刷新频率可通过修改配置文件中的 appendfsync
调整
AOF 重写机制 rewrite
随着命令不断写入 AOF 文件, 文件会越来越大
于是就需要对其中内容进行整, 剔除冗余操作, 合并修改操作 …
以达到压缩文件体积的效果
AOF 重写流程
- 执行 AOF 重写请求
- 父进程执行 fork 创建子进程
- 子进程重写 新AOF 文件的同时, 父进程需要往缓冲区中写入新的命令
- 新 AOF 文件生成完毕, 子进程发送信号通知父进程
- 父进程将缓冲区内容追加到 新的 AOF 文件中
- 新 AOF 文件替换旧 AOF 文件
重写完成
混合持久化
将 RDB 机制和 AOF 机制同时应用, 同时具有二者的优势
通过在
aof文件中
配置文件中修改aof-use-rdb-preamble yes
来设置
- AOF: 以文本方式记录每一个请求/命令
- RDB: 重写时以 RDB 二进制格式重写