Redis主从复制(Replication)是Redis内置的一种高可用性 解决方案,它允许从服务器(Slave)精确复制主服务器(Master)的数据,实现数据的冗余备份和读写分离。

一、主从复制集群搭建
1.拓扑结构
Redis主从复制的不同拓扑结构适用于不同的业务场景,选择合适的拓扑结构可以优化性能、提高可用性并满足特定需求。
1. 一主一从结构
拓扑描述:单个主节点(Master)配单个从节点(Slave)
最简单的主从集群
┌─────────┐ ┌─────────┐
│ Master │────▶│ Slave │
└─────────┘ └─────────┘
2. 一主多从结构
拓扑描述:单个主节点配多个从节点(通常2-5个)
适用于读多写少场景
┌─────────┐
│ Slave1 │
┌└─────────┘
┌─────────┐─┤ ┌─────────┐
│ Master │───│ Slave2 │
└─────────┘─┤ └─────────┘
└┌─────────┐
│ Slave3 │
└─────────┘
3. 树状复制结构(链式复制)
拓扑描述:主节点→从节点1→从节点2→...形成树状结构
从节点可以作为其他从节点的主节点
┌─────────┐
│ Master │
└─────────┘
│
┌───────┴───────┐
┌──────┐ ┌──────┐
│Slave1 │ │Slave2│
└──────┘ └──────┘
│ │
┌─────┴─────┐ ┌───┴───┐
│Slave1-1│ │Slave1-2│ │Slave2-1│
2.Docker部署主从复制集群(一主一从)
Docker部署主从复制集群https://blog.csdn.net/m0_74808313/article/details/149283482?spm=1011.2124.3001.6209
二、主从数据同步原理
1.replid和offset
在了解主从数据同步原理前,我们先来了解一下相关的概念:
-
Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid
-
offset:偏移量,随着记录在repl_baklog(缓冲区日志)中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。
2.主从全量同步
主从第一次建立连接时,会执行全量同步,将master节点的所有数据都拷贝给slave节点,流程如下:

1.从slave节点向master节点发送数据同步的请求(replid 、offset)
2.master节点判断是否是第一次的同步(replid是否相同)
3.若是第一次的同步,则master节点返回自己的数据版本信息(replid 、offset),slave节点保存返回的信息
4.master节点执行bgsave命令并生成RDB文件给slave节点
5.slave节点接收到RDB文件,清空本地数据并加载RDB文件
6.若是在master生成RDB文件期间有其他的写命令传入,都会被master节点记录到缓冲区日志文件中,最后再发送给slave节点
7.slave节点执行缓冲区日志文件中的命令,这样就保证了主节点与从节点数据的完全一致了。
其中,master节点判断是如何判断是否是第一次的同步?
因为slave原本也是一个master,有自己的replid和offset,当第一次变成slave,与master建立连接时,发送的replid和offset是自己的replid和offset。
master判断发现slave发送来的replid与自己的不一致,说明这是一个全新的slave,就知道要做全量同步了。
master会将自己的replid和offset都发送给这个slave,slave保存这些信息。以后slave的replid就与master一致了。
因此,master判断一个节点是否是第一次同步的依据,就是看replid是否一致。

3.主从增量同步
全量同步需要先做RDB,然后将RDB文件通过网络传输个slave,成本太高了。因此除了第一次做全量同步,其它大多数时候slave与master都是做增量同步。

1.slave节点向master节点发送数据同步请求
2.master节点判断是否是第一次同步
3.不是第一次同步,则进行增量同步
4.master节点在缓冲区日志中获取offset后的数据并发送给slave节点
5.slave节点执行命令完成同步
4.repl_backlog原理
repl_backlog文件是一个固定大小的循环数组,我们知道循环数组的指针到达尾部之后,在加入数据,指针会重新从0开始,这样数组头部的数据就会被覆盖。

因此,repl_backlog文件大小是有上限的,写满后会覆盖最早的数据。如果slave断开的时间过久,会导致尚未备份的数据被覆盖,无法基于repl_backlog做增量同步,只能再次做全量同步。
5.主从同步的执行时机
基于以上数据同步的原理,我们可以了解到主从同步的执行时机分别如下:
1.全量同步
-
slave节点第一次连接master节点时
-
slave节点断开时间太久,repl_baklog中的offset已经被覆盖时
2.增量同步
- slave节点断开又恢复,并且在repl_baklog中能找到offset时
三、相关面试问题
1.请你介绍一下主从同步
单节点redis的并发能力是有上线的,为了提升redis高并发下的性能,我们可以搭建redis的主从复制集群,实现读写分离。最常用的主从同步集群是一主多从,主节点负责写数据,从节点只负责读数据。
2.从节点是如何保持与主节点数据的一致的或者说一下主从同步的流程
主从同步主要是包含了两个阶段:全量同步和增量同步。
首先对于全量同步,它主要发生在从节点与主节点第一次连接时或从节点断开连接太久offset被覆盖时。
第一,slave携带replication id和offset向master发送数据同步请求,master通过replication id判断是否是第一次连接,若是第一次则返回master的节点信息,slave保存返回的信息。
第二,master执行bgsave命令生成RDB文件发送给slave,slave清除自己的数据,然后执行RDB文件。
第三,若master生成RDB期间有其他写命令传入,会被master保存到缓冲区日志中,最后发送给slave,slave执行缓冲区日志中的命令,这样就实现了主从节点的同步。
然后对于增量同步,它主要发生在slave重启或后期数据变化时。
第一,slave携带replication id和offset向master发送数据同步请求,master通过replication id判断是否是第一次连接,不是第一次连接则进行增量同步。
第二,master在缓冲区日志中获取offset之后的数据并发送给slave节点,slave节点执行命令完成同步。