边肖将与大家分享一个Redis中主从同步机制的实例分析。相信大部分人都不太了解,所以分享这篇文章给大家参考。希望你看完这篇文章能有很多收获。我们一起来看看吧!
在前一篇文章中,详细分析了redis的特点和核心原理。从本文开始,将对redis的部署结构和运行模式进行分析和解读。在真实的生产环境中,我们基本不使用单节点redis来提供服务,至少采用主从结构的哨兵或集群模式,来保证redis服务的可靠性。本文将详细解释redis的主从同步机制。
一、Redis主从有两种结构模型:
00-1010一主n从的复制结构只有一个层次,也是最常用的形式。这种复制结构通常被设置哨兵或集群结构的redis采用,通过一级从节点的复制关系,可以很好地保证服务的可用性,实现异常情况下的主从切换。
00-1010级联复制结构可以有多级复制关系,主节点的从节点可以是从属从节点的主节点。级联复制结构的应用相对较少,在多个从节点的结构下,可以在一定程度上缓解主节点的复制压力。
1.1 主从复制
Redis的主从同步从命令slave主机端口开始,通过它可以建立主从关系。SLAVEOF命令用于在redis运行时动态修改复制函数的行为。通过执行slave主机端口命令,可以将当前服务器变成指定服务器的从服务器。如果当前服务器已经是主服务器的从服务器,那么执行slave主机端口将使当前服务器停止与旧的主服务器同步,丢弃旧的数据集并开始与新的主服务器同步。另外,在从服务器上执行SLAVEOF NO ONE命令,会使从服务器关闭复制功能,从从服务器变为主服务器,原来同步的数据集不会被丢弃。利用SLAVEOF NO ONE不会丢弃同步数据集的特点,当主服务器出现故障时,从服务器可以作为新的主服务器,实现不间断运行。
下图为主从关系建立流程:
注意:
根据上面的执行过程,有一点需要注意。当我们对一个已经存在主从关系的节点执行slaveof命令时,就会结束已经存在的主从关系,节点下的所有数据都会被清空,这在生成环境下是一个相对有威胁的操作。有没有更安全的方法?当上面介绍SLAVEOF命令时,提到了NO ONE参数可以传递,也就是说,可以执行SLAVEOF NO ONE命令。这个命令只会结束主从复制关系,不会清空数据,所以安全多了。
1.2 级联复制
在主从关系建立后即将进入主从数据同步的过程。这里主要有三种情况,即主从关系刚建立后的全数据同步;初始化同步完成后的命令传播阶段;主从关系异常中断重新连接后同步模式的选择。将有两种情况:完全同步和增量同步。
00-1010当从节点启动或重新连接时(重新连接不满足增量同步的条件),sync命令将被发送到主数据库。
收到SYNC命令后,主节点将开始在后台保存快照(即RDB持久化,主从复制时无条件触发RDB),快照保存时收到的命令将被缓存。
在主节点完成RDB持久性后,它会将快照RDB文件发送到所有从节点,并在发送快照期间继续记录已执行的写命令。
接收到快照文件后,从节点丢弃所有旧数据(所有数据都将被清除)并加载接收到的快照。
在主节点发送快照并且从节点加载快照之后,主节点开始向从节点发送缓冲区中的写命令。
从节点完成快照加载,开始接收命令请求,并执行writ
每次主节点执行写命令时,它都会向从节点发送相同的写命令,从节点接收并执行接收到的写命令。(命令传播操作,从节点初始化完成后的操作)
总同步过程如下:
.com/upload/information/20211117/88/363020.jpg" alt="Redis中主从同步机制的示例分析">
在redis2.8之前,从节点无论是初始化还是断线重连后都是采用全量同步的方式,在2.8之后版本,引入PSYNC命令,在从节点断线重连后会判断是否采用增量同步。
3.2 增量同步
PSYNC具备了数据全量重同步和增量同步模式。
-
全量重同步:跟旧版复制基本是一致的,可以理解为“全量”复制。
-
部分重同步:salve断开又重新连时,在命令传播阶段,只需要发送与master断开这段时间执行的写命给slave即可,可以理解为“增量”复制。
PSYNC执行过程中比较重要的概念有3个:runid、offset(复制偏移量)以及复制积压缓冲区。
1.runid
每个Redis服务器都会有一个表明自己身份的ID。在PSYNC中发送的这个ID是指之前连接的Master的ID,如果没保存这个ID,PSYNC的命令会使用”PSYNC ? -1” 这种形式发送给Master,表示需要全量复制。
2.offset(复制偏移量)
在主从复制的Master和Slave双方都会各自维持一个offset。Master成功发送N个字节的命令后会将Master里的offset加上N,Slave在接收到N个字节命令后同样会将Slave里的offset增加N。Master和Slave如果状态是一致的那么它的的offset也应该是一致的。
3.复制积压缓冲区
复制积压缓冲区是由Master维护的一个固定长度环形积压队列(FIFO队列),它的作用是缓存已经传播出去的命令。当Master进行命令传播时,不仅将命令发送给所有Slave,还会将命令写入到复制积压缓冲区里面。PSYNC执行过程和SYNC的区别在于:salve连接时,判断是否需要全量同步,全量同步的逻辑过程和SYNC一样。PSYNC执行步骤如下:
-
客户端向服务器发送SLAVEOF命令,即salve向master发起连接请求时,slave根据自己是否保存Master runid来判断是否是第一次连接。
-
如果是第一次同步则向Master发送 PSYNC ? -1 命令来进行完整同步;如果是重连接,会向Master发送PSYNC runid offset命令(runid是master的身份ID,offset是从节点同步命令的全局迁移量)。
-
Master接收到PSYNC 命令后,首先判断runid是否和本机的id一致,如果一致则会再次判断offset偏移量和本机的偏移量相差有没有超过复制积压缓冲区大小,如果没有那么就给Slave发送CONTINUE,此时Slave只需要等待Master传回失去连接期间丢失的命令。如果runid和本机id不一致或者offset差距超过了复制积压缓冲区大小,那么就会返回FULLRESYNC runid offset,Slave将runid保存起来,并进行全量同步。
主节点在命令传播时,主数据库会将每一个写命令传递给从数据库的同时,都会将写命令存放到积压队列,并记录当前积压队列中存放命令的全局偏移量offset。当salve重连接时,master会根据从节点传的offset在环形积压队列中找到断开这段时间执行的命令,并同步给salve节点,达到增量同步结果。
PSYNC执行流程如下图:
从以上PSYNC的执行流程可以看出当slave节点断线重连以后判断是否采用增量同步的核心是slave的offset偏移量和master的偏移量相差有没有超过复制积压缓冲区大小,那么这个大小是由以下参数来配置的。复制积压缓冲区本质上是一个固定长度的循环队列,默认情况下积压队列的大小为1MB,可以通过配置文件设置队列大小:设置复制积压缓冲区大小,积压队列越大,允许主从数据库断线的时间就越长
repl-backlog-size 1mb
Redis同时也提供了当没有slave需要同步的时候,多久可以释放环形队列,默认一小时,没有salve连接时,多久释放一次复制积压缓冲区
repl-backlog-ttl 3600
四、主从复制策略
Redis采用了乐观复制的策略,也就是在一定程度内容忍主从数据库的内容不一致,但是保持主从数据库数据的最终一致性。具体来说,Redis在主从复制的过程中,本身就是异步的,在主从数据库执行完客户端请求后会立即将结果返回给客户端,并异步的将命令同步给从数据库,但是这里并不会等待从数据库完全同步之后,再返回客户端。这一特性虽然保证了主从复制期间性能不受影响,但是也会产生一个数据不一致的时间窗口,如果在这个时间窗口期间网络突然断开连接,就会导致两者数据不一致。如果不在配置文件中添加其他策略,那就默认会采用这种方式。为了防止主从不一致不可控,redis提供了以下两个参数来做约束:
min-slaves-to-write 3 min-slaves-max-lag 10
当slave数量小于min-slaves-to-write,且延迟小于等于min-slaves-max-lag时,master停止写入操作。
还有一个参数也会影响主从之间的延时:
repl-disable-tcp-nodelay:
设置成yes,则redis会合并小的TCP包从而节省带宽,但会增加同步延迟,造成master与slave数据不一致。设置成no,则redis master会立即发送同步数据,几乎没有延迟。
Redis的主从同步无论那种场景可以抽象为以下七个步骤:
1.建立socket连接
从服务器根据设置的套接字创建连向主服务器的套接字连接,主服务器接收从服务器的套接字连接之后,为该套接字创建响应的客户端状态,并将此时的从服务器看做是主服务器的客户端,也就是该从服务器同时具备服务器与客户端两个身份。
2.发送PING命令
PING命令主要有两种作用:虽然建立了套接字连接,但是还未使用过,通过发送PING命令检查套接字的读写状态是否正常;通过发送PING命令检查主服务器能否正常处理命令请求,能处理主服务器回复PONG。
3.身份验证
从服务器接收到主服务器返回的“PONG”回复,接下来就需要考虑身份验证的事。如果从服务器设置了masterauth选项,那么进行身份验证,如果从服务器没有设置masterauth选项,那么不进行身份验证。
4.发送端口信息
在身份验证步骤之后,从服务器将执行命令REPLCONF listening-port ,向主服务器发送从服务器的监听端口号。
5.数据同步
从服务器向主服务器发送SYNC命令、PSYNC命令,执行同步操作。
6.命令传播
主从服务器就会进入命令传播阶段,主服务器只要将自己执行的写命令发送给从服务器,而从服务器只要一直执行并接收主服务器发来的写命令。
以上是“Redis中主从同步机制的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/98511.html