网站建设模块化实现,郑州专业网站推广公司,东莞网站设计讯息,WordPress腾讯云cos存储插件前言
Redis为了保证服务高可用#xff0c;其中一种实现就是主从模式#xff0c;即一个Redis服务端作为主节点#xff0c;若干个Redis服务端作为主节点的从节点#xff0c;从而实现即使某个服务端不可用时#xff0c;也不会影响Redis服务的正常使用。本篇文章将对主从模式…前言
Redis为了保证服务高可用其中一种实现就是主从模式即一个Redis服务端作为主节点若干个Redis服务端作为主节点的从节点从而实现即使某个服务端不可用时也不会影响Redis服务的正常使用。本篇文章将对主从模式中为了保证主节点和从节点数据一致而实现的主从同步机制进行学习。
正文
一. 主从数据同步概述
Redis主从模式中一个高可用的Redis服务由一个Redis主节点Master后续简称为主节点和若干Redis从节点Slave后续简称为从节点组成。
Redis中采用读写分离来保证主节点和从节点之间的数据一致性具体实现如下。
主节点支持数据写入和数据读取从节点只支持数据读取主节点会与从节点之间执行主从数据同步以保证主节点数据与从节点数据一致。
主从数据同步分为如下几种情况。
从节点与主节点建立连接时进行全量同步主节点与从节点正常运行时的同步主节点与从节点连接断开后又重连时会进行增量同步或全量同步。
本篇文章将对Redis中的主从数据同步的几种情况进行学习。
二. 从节点与主节点建立连接时的全量同步
从节点与主节点建立连接时的全量同步可以用下图进行示意。 对于上图所示步骤说明如下。
从节点通过配置文件中的replicaof {masterip} {port} 获得主节点ip和port然后向主节点发送psync {repID} {offset} 指令其中repID表示主节点唯一标识offset为复制偏移量因为当前从节点与主节点尚未连接且尚未开始复制所以repID为 ?offset为-1主节点收到psync {repID} {offset} 指令后会响应从节点并发送fullresync {repID} {offset} 指令从节点会将主节点的repID和offset保存下来主节点收到psync {repID} {offset} 指令后会执行bgsave异步的生成RDB文件然后主节点将RDB文件发送给从节点从节点接收到RDB文件后会清空内存数据然后加载RDB文件的数据到内存中由于主节点生成RDB文件时是异步生成的此时主节点是非阻塞的可以继续处理业务所以在生成RDB文件期间发送RDB文件期间和从节点加载RDB文件期间主节点执行的写指令均会存放到缓冲区replication_buffer中所以当从节点加载完RDB文件后主节点会将replication_buffer中的内容发送给从节点从节点会执行replication_buffer中的指令从而达到和主节点一致的状态。
特别说明在全量同步期间主节点是非阻塞的同时从节点很大程度上是非阻塞的从节点的非阻塞表现在可以通过配置让从节点在全量同步期间使用旧内存数据来处理查询指令但是从节点在删除旧内存数据并加载RDB文件数据到内存中这段时间里从节点是阻塞的4.0版本前删除旧数据和加载RDB文件都会阻塞从节点4.0版本开始删除旧数据可以通过配置变成不阻塞从节点但是加载RDB文件还是会阻塞从节点。
最后说明一个异常情况那就是replication_buffer是有大小限制的如果replication_buffer大小超过了限制主节点会断开与从节点的同步连接此时replication_buffer的数据会被清空然后会重新开始全量同步所以replication_buffer大小需要设置一个合理值。
更多C后端开发技术点知识内容包括C/CLinuxNginxZeroMQMySQLRedisMongoDBZK流媒体音视频开发Linux内核TCP/IP协程DPDK多个高级知识点。
【文章福利】另外还整理一些C后台开发架构师 相关学习资料面试题教学视频以及学习路线图免费分享有需要的可以点击 C后端学习资料 免费领取 三. 主节点与从节点正常运行时的同步
参见redis.io/docs/manual…中的一段话。
When a master and a replica instances are well-connected, the master keeps the replica updated by sending a stream of commands to the replica to replicate the effects on the dataset happening in the master side due to: client writes, keys expired or evicted, any other action changing the master dataset.即正常运行期间主节点会向从节点发送写指令流来同步主节点的数据变更到从节点。
四. 主节点与从节点断开连接又重连时的增量同步
在第二节中提到了从节点在启动后并需要与主节点进行全量同步时会向主节点发送psync {repID} {offset} 指令这里先对repID和offset进行解释。
repID
repID即Replication ID是Redis节点作为主节点启动时或者从节点被晋升为主节点时该主节点都会生成一个新的repID思考一下什么情况还会有旧的repID后续连接到该主节点的从节点在第一次全量同步的建立连接阶段会保存一份主节点的repID所以具有相同repID的节点的数据具有相关性。
offset
offset即偏移量可以理解为当前节点的数据的逻辑时间。举个例子某个节点A的offset为500和节点A具有相同repID的节点B的offset为520那么表明节点B的数据比节点A的数据更新节点A需要再执行一些写指令才能够让节点A的数据状态和节点B一致。
有了上述两点认识现在思考一个问题主节点和从节点如果因为某些原因断开了连接而断开连接这段时间里主节点又处理了一些写指令那么从节点重新连接后应该怎么将断开连接那段时间里的写指令同步给重连的从节点通常的想法就是再执行一次全量同步在2.8之前的版本确实是这么实现的但从2.8版本开始引入了增量同步具体的实现如下。
主节点维护着一份repl_backlog_buffer缓冲区域叫做复制积压缓冲区主节点在任何时候执行写指令时都会将写指令记录在repl_backlog_buffer中repl_backlog_buffer是一个环形数组所以当数组满时后续再添加的写指令会覆盖旧的写指令因此主节点还使用了一个叫做master_repl_offset的偏移量来记录主节点的存到repl_backlog_buffer中的最新写指令的位置master_repl_offset就是上面提到的offset只不过在主节点中叫做master_repl_offset从节点也有一个偏移量叫做slave_repl_offset用来记录从节点已经从主节点的repl_backlog_buffer中同步到的最新写指令的位置主节点收到写指令后master_repl_offset增加从节点从主节点的repl_backlog_buffer同步了写指令后slave_repl_offset增加从节点断开重连后会向主节点发送psync {repID} {slave_repl_offset} 指令此时slave_repl_offset通常会小于master_repl_offset所以主节点仅需要将slave_repl_offset到master_repl_offset之间的写指令同步给从节点这就是增量同步。
特别注意如果repl_backlog_buffer中记录的从节点断开连接期间的写指令已经被后续的写指令覆盖那么此时不能执行增量同步而是需要执行全量同步所以需要将repl_backlog_buffer的大小设置一个合理的值来尽可能的保证不出现重连后需要全量同步的情况。
总结
以一张图进行总结。 原文链接详解Redis的主从同步原理 - 掘金