Redis学习笔记—Redis的持久化机制
1.为什么要持久化
- Redis是内存数据库,宕机后数据会消失。
- Redis重启后快速恢复数据,要提供持久化机制
- Redis持久化是为了快速的恢复数据而不是为了存储数据
- Redis有两种持久化方式:RDB和AOF
注意:- Redis持久化不保证数据的完整性。
- 当Redis用作DB时,DB数据要完整,所以一定要有一个完整的数据源(文件、mysql)
- 在系统启动时,从这个完整的数据源中将数据load到Redis中
- 数据量较小,不易改变,比如:字典库(xml、Table)
- 通过info命令可以查看关于持久化的信息
2.RDB介绍
- RDB(Redis DataBase),是redis默认的存储方式,RDB方式是通过快照( snapshotting )完成的。
- 这一刻的数据不关注过程
3.触发快照的方式
- 符合自定义配置的快照规则
- 执行save或者bgsave命令
- 执行flushall命令
- 执行主从复制操作 (第一次)
- 配置参数定期执行:在redis.conf中配置------》save 多少秒内数据变了多少,
漏斗设计提供性能
- 命令显式触发:在客户端输入bgsave命令。
4.RDB执行流程(原理)
- Redis父进程首先判断:当前是否在执行save或bgsave/bgrewriteaof(aof文件重写命令)的子
进程,如果在执行则bgsave命令直接返回。 - 父进程执行fork(调用OS函数复制主进程)操作创建子进程,这个复制过程中父进程是阻塞的,
Redis不能执行来自客户端的任何命令。 - 父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,并可以响
应其他命令。 - 子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后对原有文件进行原子替换。
(RDB始终完整) - 子进程发送信号给父进程表示完成,父进程更新统计信息。
- 父进程fork子进程后,继续工作。
5.RDB文件结构
- 头部5字节固定为“REDIS”字符串
- 4字节“RDB”版本号(不是Redis版本号),当前为9,填充后为0009
- 辅助字段,以key-value的形式
- 存储数据库号码
- 字典大小
- 过期key
- 主要数据,以key-value的形式存储
- 结束标志
- 校验和,就是看文件是否损坏,或者是否被修改。
6. RDB的优缺点
优点
:- RDB是二进制压缩文件,占用空间小,便于传输(传给slaver)
- 主进程fork子进程,可以最大化Redis性能,主进程不能太大,Redis的数据量不能太大,复制过程中主进程阻塞
缺点
:不保证数据完整性,会丢失最后一次快照以后更改的所有数据
7. AOF简介和配置 redis.conf
- AOF(append only file)是Redis的另一种持久化方式。Redis默认情况下是不开启的。
- 开启AOF持久化后Redis 将所有对数据库进行过写入的命令(及其参数)(RESP)记录到 AOF 文件, 以此达到记录数据库状态的目的,这样当Redis重启后只要按顺序回放这些命令就会恢复到原始状态了。
- AOF会记录过程,RDB只管结果
8.AOF原理
AOF文件中存储的是redis的命令,同步命令到 AOF 文件的整个过程可以分为三个阶段:
命令传播
:Redis 将执行完的命令、命令的参数、命令的参数个数等信息发送到 AOF 程序中。缓存追加
:AOF 程序根据接收到的命令数据,将命令转换为网络通讯协议的格式,然后将协议内容追加到服务器的 AOF 缓存中。文件写入和保存
:AOF 缓存中的内容被写入到 AOF 文件末尾,如果设定的 AOF 保存条件被满足的话, fsync 函数或者fdatasync 函数(操作系统的函数)会被调用,将写入的内容真正地保存到磁盘中。
9.命令传播
- 当一个 Redis 客户端需要执行命令时, 它通过网络连接, 将协议文本发送给 Redis 服务器。
- 服务器在接到客户端的请求之后, 它会根据协议文本的内容, 选择适当的命令函数, 并将各个参数从字符串文本转换为 Redis 字符串对象( StringObject )。
- 每当命令函数成功执行之后, 命令参数都会被传播到AOF 程序。
10.缓存追加
- 当命令被传播到 AOF 程序之后, 程序会根据命令以及命令的参数, 将命令从字符串对象转换回原来的协议文本。
- 协议文本生成之后, 它会被追加到 redis.h/redisServer 结构的 aof_buf 末尾。
- redisServer 结构维持着 Redis 服务器的状态, aof_buf 域则保存着所有等待写入到 AOF 文件的协议文本(RESP)。
11.文件写入和保存
每当服务器常规任务函数被执行、 或者事件处理器被执行时, aof.c/flushAppendOnlyFile 函数都会被调用, 这个函数执行以下两个工作:
WRITE
:根据条件,将 aof_buf 中的缓存写入到 AOF 文件。SAVE
:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。
下图是9,10,11标题内容的执行过程
12.AOF 保存模式
Redis 目前支持三种 AOF 保存模式,它们分别是:
AOF_FSYNC_NO
:不保存。AOF_FSYNC_EVERYSEC
:每一秒钟保存一次。(默认)AOF_FSYNC_ALWAYS
:每执行一个命令保存一次。(不推荐) 以下三个小节将分别讨论这三种保存模式。
不保存模式
- 在这种模式下, 每次调用 flushAppendOnlyFile 函数, WRITE 都会被执行, 但 SAVE 会被略过。
- 在这种模式下, SAVE 只会在以下任意一种情况中被执行:
- Redis 被关闭 AOF 功能被关闭 系统的写缓存被刷新(可能是缓存已经被写满,或者定期保存操作被执行)
- 这三种情况下的 SAVE 操作都会引起 Redis 主进程阻塞。
每一秒钟保存一次(推荐)
- 在这种模式中, SAVE 原则上每隔一秒钟就会执行一次, 因为 SAVE 操作是由后台子线程(fork)调用的, 所以它不会引起服务器主进程阻塞。
每执行一个命令保存一次
- 在这种模式下,每次执行完一个命令之后, WRITE 和 SAVE 都会被执行。
- 另外,因为 SAVE 是由 Redis 主进程执行的,所以在 SAVE 执行期间,主进程会被阻塞,不能接受命令请求。