文章目录
- 拓扑
- 一主一从
- 相关问题
- 一主多从
- 相关问题
- 树形主从结构
- 相关问题
- 主从复制原理
- 复制流程
- psync 命令
- 命令解析
- replicatonid
- offset
- 总结
- 运行流程
拓扑
若干个节点之间按照什么样的方式来进行组织连接
一主一从
- 都可以读,从节点可以帮主节点分担一部分的压力
- 只有主节点能写
解决了单点并发量不高和单点可能出现故障的情况
相关问题
- 写请求太多
但是如果写请求太多,也会给主节点造成一些压力。
- 此时我们可以通过关闭主节点的
AOF
,只在从节点上开启AOF
的方式降低主节点的压力 AOF
需要将数据写到硬盘上,而写硬盘比写内存要慢上不少,因此让主节点就只写内存,这样主节点能支持的并发量就更大了
- 数据丢失
但是这种设定方式,有一个严重的缺陷:主节点一旦挂了,不能让他自动重启(如果自动创奇,此时没有AOF
文件,就会丢失数据,进一步的主从结构,会把从节点的数据也给删了)
改进办法:当主节点挂了之后,就需要让主节点从从节点这里获取到 AOF
文件,然后再启动
一主多从
在实际开发中,读请求的数量是远远超过写请求的,此时我们就可以用一主多从的结构
- 主节点上的数据发生改变,就会把改变的数据同时同步给所有的从节点
相关问题
- 网络带宽压力
随着从节点个数的增加,同步一条数据,就需要传输多次,主节点的网络带宽要压力是很大的
解决办法:使用树形主从结构
树形主从结构
可以有效的缓解主节点网络带宽压力大的情况
- 这样就把同步数据的网络压力,均摊到多个节点上了,主节点就不需要那么高的网络带宽了
相关问题
- 同步时间变长
一旦数据进行修改了,同步数据的延时是比一主多从结构要长的,
主从复制原理
复制流程
- 先保存主节点的 IP 和端口(在一个变量中)
- 然后建立一个
TCP
连接(三次握手) - 通过
ping
命令,验证主节点是否能够正常工作(站在应用程序角度)- 上面的
TCP
三次握手,验证的是通信双方能否正常读写数据,而不是能否正常工作(站在系统层面) - 检查路修好了没(三次握手);检查这辆车子是不是好的(
ping
)
- 上面的
redis
主节点如果开启了密码,就会触发“权限认证”
上面的都是准备操作,最关键的复制操作就是第五步和第六步
- 同步数据集:相当于全量同步。在进行同步的一瞬间,一次性把所有的数据都给我
- 命令持续复制:相当于增量同步。后续再有数据变化,继续进行同步
psync 命令
redis
提供了一个 psync
命令,完成数据同步的过程
- 不需要我们手动执行,
redis
服务器会在建立好主从同步关系之后,自动执行psync
- 从节点负责执行
pysnc
,从节点从主节点这边拉取数据(从节点主动要,而不是主节点主动给)
语法格式为:
PSYNC replicationid offset
命令解析
replicatonid
replicationid
:理解成复制 Id,是主节点在启动的时候生成的(从节点变成主节点的时候也会生成,下面有谈到)- 即使是同一个主节点,每次重启,生成的
replication id
都是不同的 - 从节点和主节点建立了复制关系,就会从主节点这边获取到
replication id
- 此处讨论的都是一个主节点,多个从节点。
- 即使是同一个主节点,每次重启,生成的
我们可以通过 info
命令,获取到 replication id
info replication
- 一般情况下,
replid2
是用不到的
使用到
replid2
的情况
- 有一个主节点 A,还有一个从节点 B。 A 生成
replid
,B 获取到 A 的replid
- 如果 A 和 B 通信过程中出现了一些网络抖动,B 可能就会认为 A 挂了,于是 B 就会自己成为主节点,给自己生成一个
replid
- 此时 B 也会记得旧的
replid
,就是通过replid2
- 后续网络稳定了,B 还可以根据
replid2
重新回到 A 的怀抱
- 需要手动干预。不过哨兵机制可以自动完成这个过程
offset
可以理解成偏移量,主节点和从节点上都会维护偏移量(整数)
- 主节点上:主节点会收到很多的修改操作的命令,每个命令都要占据几个字节,主节点会把这些修改命令的字节数进行累加,就会得到一个逐渐变大的数字
- 从节点上:描述了现在从节点这里的数据同步到哪里了
- 如果从节点和主节点这里的偏移量一样,就说明同步完成了
- 从节点(
slave
)每秒钟上报自身的复制偏移量给主节点
总结
replicationid
和 offset
共同描述了一个“数据集合”
如果发现两个机器,replicationid
一样,offset
也一样,就可以认为这两个 redis
机器上存储的数据就是完全一样的
- 主服务器看做银行总行,从服务器看做分行
- 总行里面有很多客户,每个客户都有一个自己的账户,用
replicationid
表示账户,offset
表示订单数量 - 比如张三的账户
replicationid
是123123
,他此时转出 100 元,总行实时记录,订单数量offset
为 1,随后同步给分行
- 总行里面有很多客户,每个客户都有一个自己的账户,用
- 只要总行和分行里面,账户号
replicationid
和订单数量offset
一样,就说明两边的数据是一样的,如果分行的订单数量offset
比总行的少,那就说明还没同步完成
运行流程
-
FULLRESYNC
:全量数据的同步 -
CONTINEU
:增量数据的同步 -
ERR
:比较老版本的redis
服务器不支持psync
(可以用sync
,会阻塞redis
服务器) -
psync
这里可以从主节点获取全量数据,也可以获取一部分数据,主要就是看offset
这里的进度offset
写作-1
,就是获取全量数据- 获取所有数据是最稳妥的,但是会比较低效
offset
写具体的正整数,则是从当前偏移量位置来进行获取- 如果从节点之前已经从主节点这里复制过一部分数据了,就只需要把新的之前没复制过的数据搞过来即可
不是从节点索要哪部分,主节点就一定给哪部分。主节点会自行判断,看当前是否方便给哪部分数据,不方便就只能给全量数据了
什么时候进行全量复制?
- 首次和主节点进行数据同步
- 主节点不方便进行部分复制的时候
什么时候进行增量复制?
- 从节点之前已经从主节点上复制过数据了。因为网络抖动或者从节点重启了,从节点需要重新从主节点这边同步数据,此时看看能不能只同步一笑部分(大部分数据都是一致的)
**