纳雍政府网,虐杀原形2高压,优美的散文
redis 的主从同步(复制)
假设有两个 redis 实例 → a 和 b
b 实例的内容与 a 实例的内容保持同步
那么称 a 实例是主数据库,b 实例是从数据库
这个过程称为主从同步
slaveof 主数据库地址 主数据库端口
redis> slaveof 主数据库地址 主数据库端口
$ reids-server --port 6380 --slaveof 主数据库地址 主数据库端口
redis> slaveof no one
复制分为连接建立,数据同步(sync)和命令传播(command propagate)三个阶段
连接建立这里不说,与复制原理无关
下面主要讲数据同步与命令传播两个阶段
redis 从 2.8 版本之后优化了复制功能,咱们先从旧版本的复制说起:
步骤 | 主服务器 | 从服务器 |
---|---|---|
向主服务器发送 sync 命令 | ||
收到 sync 命令,执行 bgsave 生成 rdb 文件 | ||
使用缓冲区记录从现在的写命令 | ||
将生成的 rdb 文件发送给从服务器 | ||
将缓冲区内的写命令发给从服务器 | 接收并载入 rdb 文件 | |
接收并执行主服务器发送来的写命令 | ||
发送客户端发过来的写命令 | ||
执行主服务器发送过来的写命令 | ||
与同步流程一致 | 与同步流程一致 |
经过上述步骤之后主从服务器的状态可以始终保持一致。
细心的读者已经发现了旧版复制的一些问题:
断线重连需要重新走一次同步的流程,而同步流程中的主服务器生成 rdb 文件和从服务器执行 rdb 文件都是特别密集的 io 操作,这会让断线重连的成本很高
于是从 2.8 版本之后,redis 使用了新的技术来防止重新执行同步流程
步骤 | 主服务器 | 从服务器 |
---|---|---|
向主服务器发送 psync 命令 | ||
收到 psync 命令,执行 bgsave 生成 rdb 文件 | ||
使用缓冲区记录从现在的写命令 | ||
接收并执行主服务器发送来的写命令 | ||
将缓冲区内的写命令发给从服务器 | 接收并载入 rdb 文件 | |
将生成的 rdb 文件发送给从服务器 | ||
发送客户端发过来的写命令 | ||
执行主服务器发送过来的写命令 | ||
发送 psync 命令 | ||
向从服务器发送断线过程中的写命令 | ||
执行写命令 |
新版复制经过上述步骤,也可以实现主从数据库状态的一致。
在断线重连过程中,只需要重新执行断线过程中未同步的命令即可,这样就比旧版的复制节省了很多 io 操作
那么这个断线重连的是怎么实现的呢?
redis 的部分重同步借助了4个变量:
也许将这4个变量列出来之后,有读者就可以直接想象出来是怎么实现的了,对,没错,就是这么实现的
步骤 | 主服务器 | 从服务器 |
---|---|---|
发送命令 psync 主数据库的运行id 断开前最新的命令偏移量 | ||
判断 1. 运行id是否能够对应 2. 断开前最新的命令偏移量是否在队列中 满足上述条件可以执行部分重同步,否则执行完全同步 | ||
发送给从数据库偏移量之后的命令 | ||
执行命令 |
redis 在很多细节上优化了性能,主从同步(复制)的优化只是其中的一方面。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
MongoDB中数据的替换方法实现类Replace()函数功能详解
理解Redis持久化,RDB持久化和AOF持久化的不同处理方式
网友评论