Redis主从模式原理

前言

redis在高并发场景下,可以称作是一个利器,一方面可以作为缓存技术,另一方面可以作为分布锁的实现方案。

   对于单节点的redis来说,它会有自己的瓶颈,所以往往会采用redis集群来负载高并发。其中应用比较多的就是主从模
式,也就是采用读写分离模式。

在这里插入图片描述
下面来首先来探讨下,redis的主从模式的搭建,以及主从同步的原理。

搭建过程

首先采用的是一主两从的方式,(本机IP:192.168.0.2),如图:

在这里插入图片描述
master:192.168.0.2:7001
slave-1:192.168.0.2:7002
slave-2:192.168.0.2:7003

docker执行的命令如下:

 #master 节点命令
docker run -d -p 7001:6379 --network redis --name redis-master --privileged=true -v /Volumes/bto/redis/master-slave/7001:/data redis:6.2.4
 ##slave-1 节点命令
docker run -d -p 7002:6379 --network redis --name redis-node-1 --privileged=true -v /Volumes/bto/redis/master-		slave/7002:/data redis:6.2.4
 ##slave-2 节点命令
docker run -d -p 7003:6379 --network redis --name redis-node-2 --privileged=true -v /Volumes/bto/redis/master-slave/7003:/data redis:6.2.4

执行完上述命令后,执行docker ps查看运行结果,如下图:
在这里插入图片描述
上图可以看出,已经运行起来三个redis实例,但是此时的三个实例之间还不是主从关系,接下来建立主从,以redis-slave-1为例:

可以通过docker命令进入容器内,或者在宿主机上直接操作,这里我选择的是在宿主机上直接操作,首先链接7002实例,命令如下:

redis-cli -h 192.168.0.2 -p 7002

进入后,执行命令:

slaveof 192.168.0.2 7001

来指明它的主节点是7001。(7003同理)

【注意】从redis 5.0版本开始,该命令已经过时,应该用replicaof命令来代替slaveof。我本地用的是6.4.2,主要是习惯了slaveof。官网说明如下图:
在这里插入图片描述
此时连接上7001,执行如下命令,查看从节点信息:

info replication

在这里插入图片描述
可以看出slaves是2个节点。其中的ip=172.21.0.1是docker容器中的ip。

然后来验证下:

在master-7001上进行新增,然后看下7002,7003从节点的数据。执行结果如下图:
在这里插入图片描述

	在7001的主节点上,新增加了{key:value} = {username:zhangsan}的数据。然后在7002和7003上分别获取,得到了相
同的结果。

尝试在从节点 7002、7003节点上进行增加操作,执行结果如图所示:
在这里插入图片描述
此时,redis会返回一个error结果:

READONLY You can't write against a read only replica.

就从节点是只读,无法写入。

其实上述搭建的过程很简单,没有太大的难度。接下来分析下主从数据同步的原理。

对于主从数据同步的原理呢,分为全量同步和增量同步。这篇博客主要探讨全量同步。

全量同步

在描述全量同步的过程之前,先来认识两个概念:

  1. replid:是实例节点的唯一表示。
  2. offset:数据的偏移量。
    也就是说每个redis实例在启动的时候,都会有一个replid唯一表示,实际上完整叫master_replid,因为首次启动的redis时候它都是一个主节点(前提:没有在配置文件中进行配置主从),而offset可以理解成分页数据。比如:启动7001、7002后的信息如下:
    在这里插入图片描述
    上图左侧为redis:7001,右侧为redis:7002。在没有进行主从配置的时候,它们都是主节点,也就是role:master(上图红色框),同时都有各自的replid(绿色狂),其中:
replid:
	7001-replid: c1e5b2e6c931b5b40bb80ec79ad07babfce7e44d
	7002-replid:50452115cb9093ac6562357dfb59eb5059c33aa5
而各自的offset为:
	7001-offset: 0
	7002-offset:0

下面探讨下,主从数据同步的原理,如图:
在这里插入图片描述
上图是redis进行数据全量同步的过程,这里分成了三个阶段:

	【第一阶段】:当redis实例节点7002,执行slaveof(或replicaof) 192.168.0.2 7001 命令的时候,
会向master发送自己的replid和offset给7001,然后尝试进行增量同步。当7001接收到后发现replid与
自己的不一样,说明是第一次建立主从关系,所以就会拒绝【增量同步】,而是选择【全量同步】,
并把自己(7001)的replid和offset发送给7002,7002再接收这些信息后会保存起来。

	【第二阶段】:在7001向7002发送replid、offset信息的同时,会有一个【独立进程】生成rdb文件,
然后把生成好的rdb文件发送给7002。7002再接收到数据后,会把本地的数据进行清空(包括内存与rdb文件),
然后读取7001发送过来的rdb文件,并把数据加载到内存中。但是在7001(master)生成rdb的时候
是很耗时的,同时因为主节点是可以被写入的,因此在生成rdb的时候,如果有client端对master节点(7001)
进行了操作,后台进程会把这些操作命令写入到一个日志中---repl_backlog。

	【第三阶段】由于在第二步生成了repl_backlog,所以master节点会采用一定策略把repl_backlog
发送给从节点,从节点再接收到日志文件后,再进一步同步本地的数据。

该三阶段就是redis主从全量同步的流程。具体这个流程是怎么来的呢?这是通过日志分析出来的,接下来看下具体的日志信息。

全量数据同步过程

  1. slave节点根据配置的master节点信息,连接上master节点,并向master节点发送SYNC命令;
  1. master节点收到SYNC命令后,执行BGSAVE命令异步将内存数据生成到rdb快照文件中,同时将生成rdb文件期间所有的写命令记录到一个缓冲区,保证数据同步的完整性;
  1. master节点的rdb快照文件生成完成后,将该rdb文件发送给slave节点;
  1. slave节点收到rdb快照文件后,丢弃所有内存中的旧数据,并将rdb文件中的数据载入到内存中;
  1. master节点将rdb快照文件发送完毕后,开始将缓冲区中的写命令发送给slave节点;
  1. slave节点完成rdb文件数据的载入后,开始执行接收到的写命令。
  1. 以上就是master-slave全量同步的原理,执行完上述动作后,slave节点就可以接受来自用户的读请求,同时,master节点与slave节点进入命令传播阶段,在该阶段master节点会将自己执行的写命令发送给slave节点,slave节点接受并执行写命令,从而保证master节点与slave节点的数据一致性。

日志分析

为了方便查看日志的流程,我在宿主机上进行手动进行启动7001、7002两个redis实例,并通过redis-cli连接7002,如下图:
在这里插入图片描述
然后我在7001中随便添加了几个数据(这里不再演示),主要是为了展示offset。

建立主从,在7002中执行命令:

replicaof 127.0.0.1 7001

在这里插入图片描述
输出的日志:
在这里插入图片描述
上屏是7001的日志,下屏是7002的日志。

首先,7002开始尝试能发ping通7001,来确定是否可以建立连接 ,如下图:
在这里插入图片描述
然后通过后,7002开始尝试向7001请求数据,并把自己的repid、offset发给7001,如下图:
在这里插入图片描述
采用的是

partial resynchronization:增量同步
repid: 095911a80dc2a318ea60b16b2a0260228896ee7f(7002的repid)
offset: 1

然后7001接收到7002发送来的信息,如下图:
在这里插入图片描述
后台进程为26853,生成完rdb文件后,发送给7002。

7002此时接收到来自7001的rdb文件,如下图:
在这里插入图片描述
开始全量同步,其中包括了【Flushing old data】清空旧的数据,【 Loading DB in memory】把rdb中的数据加载到内存中。这样就完成了主从同步,其实背后还有一个repl_backlog的过程,只是没有在日志中显示。

redis主从同步策略

主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步

转自:https://zhuanlan.zhihu.com/p/537080944

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值