Redis主从问题

目录

1.1.主从集群结构介绍

1.2.如何搭建主从集群

1.2.1  启动多个Redis实例

1.2.2.建立集群方法:

1.3. 全量同步

1.3. 增量同步

1.3.1 repl_baklog原理

1.4. 主从同步优化

1.5 总结


因为单节点Redis他的并发能力是有上限的,但是为了更好的提高Redis的并发能力,那就要搭建主从集群,实现读写分离的目标

1.1.主从集群结构介绍

这是一个Redis主从集群结构图:

如图所示,图中的集群中有1个master节点和两个slave节点(也可以叫replica)。当我们访问主从集群通过Redis的Java客户端的时候,应该做好路由:

1.1.1 当我们写响应的操作,并且要访问Master主节点的时候,主节点会把消息同步给他相应的两个子节点slave/replace。

1.1.2 主节点是可读可写的,但是从节点只能读不能写,因此,如果要读取信息操作,最好是访问从节点slave,从而减少并发压力;

1.2.如何搭建主从集群

1.2.1 首先,我们在虚拟机中利用docker创建三个容器,这三个容器用来搭建集群,例如下图:

 

1.2.1  启动多个Redis实例

我们把响应的docker -compose的yaml文件放入虚拟机中,这个文件是用来搭建集群的,您所在的公司或者学校会提供,或者你再接去网上找一个,或者你直接自己创建一个,我把内容放下面了:

将这个文件放进你虚拟机的redis文件夹中并且执行以下操作运行集群:

docker compose up -d

如果出现以下结果,那就说明启动成功

这时候,我们可以通过docker -ps查看我们的容器已经正常启动了1.2.2.建立集群

1.2.2.建立集群方法:

          虽然我们已经创建了三个redis实例,但是并没有让其产生主从关系,因此,我们要从让他们形成主从关系,按照下面操作:

Redis5.0以前

slaveof <masterip> <masterport>

Redis5.0以后

replicaof <masterip> <masterport>

其中有两种模式:

1. 永久生效:在redis.conf文件中利用slaveof命令指定master节点

2. 临时生效:直接利用redis-cli控制台输入slaveof命令,指定master节点

这里,我们首先来进行临时生效的测试:

先进入r2,并且认r1为主节点:

docker exec -it r2 redis-cli -p 7002

slaveof 192.168.150.101 7001

同理,进入r3,并且让r1成为master主节点:

docker exec -it r3 redis-cli -p 7003

slaveof 192.168.150.101 7001

这时候我们可以进入r1,并且查看了:

连接r1: docker exec -it r1 redis-cli -p 7001

查看集群状态 :info replication

如果成功,结果是如图:

从图中不难看出,这边的节点9001为master主节点,而他有两个slave与他连接:

分别是:9002的slave0 和9003的slave1

接下来可以进行测试,在r1,r2,r3中分别进行如下操作:

set num 123 get num

get num

我们会发现,在master中,可以写入操作,也可以读取操作,但是在两个slave中不能写操作,但是我们不难发现,我们在master中写入的操作同步到两个slave中了,而且两个slave可以读取,也验证了我们的slave节点的只读不写。也就是说,读写的操作已经分离。

1.3. 主从同步的原理

1.3.1. 全量同步

从上面的结果中我们不难看出,主节点写入的操作信息回同步到他相应的slave节点上,为此,也说明了主从之间完成了数据同步。

那么这个同步的实现,接下来回说明:

当主从第一次建立连接的时候,master和slave会执行全量同步,将master节点的所有数据都拷贝给slave节点,流程:(这个图是网络上看到的,可以借助理解)

从图中我们不难看出,会有两中同步:全量同步 以及 增量同步;

               全量同步是第一次同步时,master节点会将自己的版本信息全部同步给slave节点,但是我们该怎么判断是否是第一次同步呢?

                有以下几点可以作为判断依据:

1.Replication Id:简称replid,是数据集的标记,replid一致则是同一数据集。每个master都有唯一的replidslave则会继承master节点的replid

2.offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slaveoffset小于masteroffset,说明slave数据落后于master,需要更新。

结合上面的,slave向master申请同步数据的第一步就是把自己slave的offsetreplication id传递给master。master会判断是否给全量还是增量同步,如果是增量同步,该同步那些

        由于我在进行slaveof之前,所有的节点都为master,都有自己相对应的replid和offset,所以当执行slaveof建立主从关系的时候,发出的repid和offset是自己,肯定不与master不一样,当master接到传过来的replid和offset和自己不一样,说明是一个全新的slave,就会选择进行全量同步了,这时,master会将自己的replid和offset发给这个slave,slave会将自己的数据清空,并且把master的信息全部同步到本地,从此,slave和master就一致了。

        总结:master判断一个节点是否是第一次同步,就是通过replid是和和自己的一致:

通过下图加强理解:

流程如下:

1. slave节点请求增量同步

2. master节点判断replid,发现不一致,拒绝增量同步

3. master将完整内存数据生成RDB,发送RDBslave

4. slave清空本地数据,加载masterRDB

5. masterRDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave

6. slave执行接收到的命令,保持与master之间的同步

1.3. 2. 增量同步

上面介绍了全量同步,那么增量同步也是相同的原理:

        就是只更新slave与master存在差异的部分数据

如下图:

简单的说就是,slave不是第一次同步,就把master中新增加的增加同步到自己哪里。也可以理解为把比master少的东西全部补充拿过来;

1.3.3.  repl_baklog原理

当master给slave传输数据的同时,master又写了新的操作的时候,行的操作会放进repl_baklog积压缓存区中,等master传输完后会继续把新的数据同步给slave;

repl_baklog中会记录Redis处理过的命令及offset,包括master当前的offset,和slave已经拷贝到的offset

slave与master的offset之间的差异,就是salve需要增量拷贝的数据了,随着不断有数据写入,master的offset逐渐变大,slave也不断的拷贝,追赶master的offset;

一直到这个数组被填充满;

此时,如果有新的数据写入,就会覆盖数组中的旧数据。不过,旧的数据只要是绿色的,说明是已经被同步到slave的数据,即便被覆盖了也没什么影响。因为未同步的仅仅是红色部分。

但是,如果slave出现网络阻塞,导致master的offset远远超过了slave的offset;如果master继续写入新数据,master的offset就会覆盖repl_baklog中旧的数据,直到将slave现在的offset也覆盖

棕色框中的红色部分,就是尚未同步,但是却已经被覆盖的数据。此时如果slave恢复,需要同步,却发现自己的offset都没有了,无法完成增量同步了。只能做全量同步

repl_baklog大小有上限,写满后会覆盖最早的数据。如果slave断开时间过久,导致尚未备份的数据被覆盖,则无法基于repl_baklog做增量同步,只能再次全量同步。

1.4. 主从同步优化

为什么要主从同步:

                        主从同步可以保证主从数据的一致性

下面有几种方式来实现同步优化:

1. 在master中配置repl-diskless-sync yes启用无磁盘复制,避免全量同步时的磁盘IO。

2. Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO

3. 适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步

4. 限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力

主-从-从的结构图:

1.5 总结

        

1.5.1. 简述全量同步和增量同步区别?

1.5.1.1 全量同步:master将完整内存数据生成RDB,发送RDB到slave。后续命令则记录在repl_baklog,逐个发送给slave。

1.5.1.2.增量同步:slave提交自己的offset到master,master获取repl_baklog中从offset之后的命令给slave。

1.5.2. 什么时候执行全量同步?

1.5.2. 1. slave节点第一次连接master节点时

1.5.2. 2.slave节点断开时间太久,repl_baklog中的offset已经被覆盖时

1.5.3. 什么时候执行增量同步?

1.5.3.1. slave节点断开又恢复,并且在repl_baklog中能找到offset时

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值