redis主从复制中数据同步的原理

前言

redis主从复制解决的是redis主服务和从服务之间的数据同步的问题,主从服务是redis集群要解决的一个基础且重要的问题,学习一下还是很有必要的。

一个简单例子

下图是一个简单的主从服务,master有一个slave从服务,两台机器都会向外提供读,但写只能在主服务上,新写入redis的数据会同步给从服务,这个同步的过程叫做主从复制。
主从模式
除此之外,一个主服务可以有多个从服务,而从服务只能对应一个主服务,另外从服务也可以有自己的从服务。如果复杂一点的话,主从服务的关系就是一棵树,主服务就是顶端的根节点,其他的都是从服务,数据从根节点“流入”,流向子孙结点。
复杂的主从结构

相关命令

1)salveof

slaveof <host> <port>
salveof命令可以建立和解除主从关系,例如:slaveof 192.168.1.1 6379可以将当前redis设置为192.168.1.1上的从服务,当前的服务的数据会被清除,接下来就会同步主服务的数据过来了。slaveof no one会解除主从关系,当前的服务重新成为主服务,数据不再同步。

2)info replication

info replication可以查看主从复制相关信息。下面分别展示一下主服务和从服务的相关信息。

主服务上执行:
master
role:master:表明这是一个主节点
connected_slaves:1:当前有一个从节点
slave0:ip=172.18.0.3,port=6379,state=online,offset=131,lag=0: 显示了这个这个从节点的信息,如果有多个从服务,还会有salve1…等等的心思。很明显,这里显示了从节点的ip和端口,state表示从节点的当前的状态。offset用于数据同步,lag表示从节点“落后”了多少数据,lag=0表示主从结点的数据是一致的。
master_replid:372e55af72a6c4e4ed5b804fb0c0c06c3ab61258:master的id值,用于唯一标记一个结点,从节点同步时会记住这个id,同步时会校验主结点的id是否匹配。
master_repl_offset:131:这是一个偏移量,主节点会将新写的数据缓存在一个队里里面,从节点同步时会保存当前同步的偏移量,从节点同步主节点数据时,会将主机点的id和上次保存的偏移量发送给主节点,主节点收到同步请求后,如果id和自己的id相同而且发送来的偏移量比自己记录的偏移小,说明新写的数据没同步,遍将N字节的数据和偏移量+N一并发送给从节点。从节点收到数据后,记住偏移量用于下一次同步使用。

在从节点上执行:
slave
role:slave:表明此节点是从服务
master_host:master:主节点ip,由于我使用的是docker,在docker实例中,我指定了主节点的hostname为master,而docker的user bridge网络类型为连在这个网络下的主从结点提供了自动DNS服务,所以我配置的master最终会被解析成主节点的ip
master_port:6379:主节点端口
master_replid:372e55af72a6c4e4ed5b804fb0c0c06c3ab61258:主节点的id,注意看主节点的是一致的。
master_repl_offset:3883:偏移量,用于同步数据,同上。

同步原理

Redis在2.8之前使用SYNC命令同步,之后便用PSYNC命令替代了SYNC命令。下面重点介绍PSYNC命令。

全量同步和部分同步

PSYNC同步数据有两个模式:全量和部分,从节点发送PSYNC <id> <offset>命令请求个主节点进行数据同步,主节点根据情况选择同步的方式。

  1. 全量同步用于从节点第一次同步主节点数据。主节点会fork出一个进程进行RDB备份,主节点会将RDB文件和缓冲区的数据发送给从节点完成数据同步。
  2. 部分同步用于第一次同步之后的数据同步,这时候只需要同步缓冲区里面新增的写命令即可。

几个概念

在解释同步的过程之前先澄清几个概念。

1)复制缓冲区

主从结点是通过生成RDB快照文件进行数据同步的。假设现在数据同步,主节点开始生成RDB文件。由于同Fork进程的方式,主进程还在处理客户端的写命令,那新写入redis的数据如何同步?(fork相关有个重要的概念:copy on write,fork出的子进程备份的RDB文件是旧的,在fork后写入主进程的数据子进程不能获取到,所以RDB文件里面只有旧数据)Redis使用了一个队列缓冲区暂时存储新的写命令,待从节点恢复完RDB文件,再把缓冲区的数据发送给从节点,一次来达到数据的一致性。

2)结点ID

每个redis实例运行都会生成自己的id,这个id用于数据同步和主从关系的验证等等。上面介绍info replication命令时,输出的信息中就包含主从结点的id和偏移量。

3)复制偏移量

完成第一次数据同步之后,新的写命令都将入到固定大小的缓冲区队列中,从节点同步是只需要同步缓冲区的数据就可以了。那么问题了,从节点应该同步缓冲区中那一部分的数据呢?偏移量便是用来解决这个问题的。假设主从结点完成一次同步,那么他们的保存的偏移都是相等的。这时候主节点又写入了N字节数据,主节点偏移量+N。这时候从节点发送PSYNC请求同步,主节点比较发送来的偏移量offset和自己当前的偏移量offset+N,发现有N字节的新数据,于是将N字节的数据发送给从节点。从节点的偏移量变成了offset+N,自此,数据又达成一致。

partial data sync

但是有一些情况,需要重新进行RDB快照同步的。例如,从节点由于网络抖动等原因太久没和主节点同步,或者主节点短时间有大量的写入,超过了缓冲区大小。主节点一看offset+N-offset>缓冲区大小,这时候就需要进行RDB快照同步了。

rdb sync

4)PSYNC命令

主从结点通过PSYNC命令进行数据同步。

从节点发送PSYNC命令:

  • 第一次同步发送PSYNC ? -1到主节点请求数据同步。
  • 第一次同步后发送PSYNC id offset到主节点请求数据同步,主节点根据offset值进行部分同步或者全量同步。

主节点处理PSYNC命令:

  • 主节点返回FULLRESYNC <id> <offset>进行全量同步。
  • 主节点返回+CONTINUE进行部分同步
  • 主节点返回-ERR,表示主服务redis版本低于2.8,不能PSYNC命令,从服务将使用SYNC命令进行同步。

使用PSYNC同步过程:

同步过程

同步原理

部分同步原理

部分同步原理

全量同步原理

全量同步原理

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值