在这里插入图片描述

📃个人主页:island1314

⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞

  • 生活总是不会一帆风顺,前进的道路也不会永远一马平川,如何面对挫折影响人生走向 – 《人民日报》


前言

在非分布式系统中,即仅有一个主机提供服务时,如果该主机发生故障,整个服务将会崩溃。这种情况被称为 ==单点问题,它不仅影响了系统的可用性,还限制了系统的并发处理能力。

为了解决单点问题并提高服务的并发处理能力,可以引入分布式系统。通过多个主机共同完成一个服务:

  • 提升并发能力:多台服务器分担负载,支持更大数量的客户端请求。
  • 避免单点故障:即使一台服务器出现故障,其他服务器仍能继续提供服务,确保业务连续性。

在分布式系统中,Redis通常采用以下三种部署模式之一:

主从模式

  • 定义:包含一个主服务器(Master)和多个从服务器(Slave)。所有写操作都在主服务器上执行,而读操作可以在从服务器上分散进行。
  • 数据一致性:从服务器的数据是从主服务器复制而来,且不允许直接修改,以保证数据的一致性和完整性。
  • 工作原理:写入操作集中在主节点,查询操作则被分配到从节点,确保主节点的数据是最新的,同时减轻其负载。

主从 + 哨兵模式

  • 概述:在主从模式基础上加入了哨兵(Sentinel)组件,用于监控集群健康状况,并在主节点故障时自动选择一个新的主节点。
  • 功能:提供了自动化的故障检测与恢复机制,减少了人工干预的需求。

集群模式

  • 特点:允许多个Redis实例协同工作,形成一个逻辑上的大型数据库,支持水平扩展。
  • 适用场景:适合需要 更大存储容量或更高性能的应用环境。

一、主从模式

主从复制作用

  1. 解决单点问题,通过数据复制多个副本部署到其他服务器,满足 故障恢复和负载均衡 等需求
  2. 复制功能 是高可用Redis的基础,哨兵和集群 都是在复制的基础上构建的
  3. 从节点上的数据要跟随主节点变化,从节点的数据要和主节点保持一致
  4. 主从模式,从 要是针对 “读操作”,进行并发量和可用性的提高
  5. 写操作,无论是可用性还是并发量,都非常依赖主节点,主节点不能搞多个

1. 建立主从复制

参与复制的Redis实例划分为 主节点(master) 和 从节点(slave),其特性如下:

  • 每个从结点只能有一个主节点,而一个主节点可以同时具有多个从结点
  • 复制的数据流是单向的,只能由主节点到从节点。
  • 从节点的数据不允许修改!!!只能读取数据
配置

大部分人手上都只有一台主机或者云服务器,此时想要打造一个分布式系统就需要用一些其他技巧,而不是真的在多个主机上部署分布式。

其实在一台主机上,是可以允许多个 redis-server 进程的,只要保证 每个进程的端口号不同(默认端口号:6379),那么就可以有多个 redis-server 存在。

① 创建从节点的配置文件:

root@VM-8-10-ubuntu:~# mkdir redis
root@VM-8-10-ubuntu:~# cd redis/
root@VM-8-10-ubuntu:~/redis# cp /etc/redis/redis.conf ./slave1.conf
root@VM-8-10-ubuntu:~/redis# cp /etc/redis/redis.conf ./slave2.conf
root@VM-8-10-ubuntu:~/redis# ls
slave1.conf  slave2.conf

② 修改从节点配置文件

  • 找到port选项:默认的端口号是6379,此端口号修改为其它端口,不要与主节点冲突。
  • 找到daemonize选项,保证该选项是yes,这样 Redis才能在后台运行。

③ 启动后通过ps查看,可以看到同时有三个Redis在运行:

root@VM-8-10-ubuntu:~/redis# redis-server ./slave1.conf
root@VM-8-10-ubuntu:~/redis# redis-server ./slave2.conf
root@VM-8-10-ubuntu:~/redis# ps -ajx | grep redis
      1 1220343 1220343 1220343 ?             -1 Ssl      0   0:00 redis-server 0.0.0.0:6381
      1 1224091 1224091 1224091 ?             -1 Ssl      0   0:00 redis-server 0.0.0.0:6380
1214575 1220393 1220392 1214521 pts/1    1220392 S+       0   0:00 grep --color=auto redis
      1 3708413 3708413 3708413 ?             -1 Ssl    115  90:03 /usr/bin/redis-server 0.0.0.0:6379

④ 启动不同的客户端 配置 主从结构

此时三个节点是单独的三个服务,还没有构成主从结构,如下:

image-20250707161616777

配置主从需要通过slaveof,有以下三种方式:

  1. 配置文件中加入 slaveof {masterHost} {masterPort} 随Redis启动生效。【更推荐这种方法】
  2. 在redis-server启动命令时加入 --slaveof {masterHost} {masterPort} 生效。
  3. 直接使用redis命令:slaveof {masterHost} {masterPort} 生效。

此处通过修改配置文件完成主从配置,因为其是持久的,后两种方式在每车次启动时都要输入额外的命令。

在两个 slave.conf, shift+g 到最末尾加上以下内容(这里以 6379 为主节点)

image-20250707162105603

注意:有秘密设置的还要给从节点加上一句话 masterauth password 加在 slaveof 下面,如果不这样的话后面会出问题

Redis 的配置文件修改之后需要重新启动,具体操作如下:

root@VM-8-10-ubuntu:~/redis# ss -tnlp | grep redis-server	# 查看 pid 
LISTEN 0      511          0.0.0.0:6380       0.0.0.0:*    users:(("redis-server",pid=1224091,fd=6))    
LISTEN 0      511          0.0.0.0:6381       0.0.0.0:*    users:(("redis-server",pid=1220358,fd=6))    
LISTEN 0      511          0.0.0.0:6379       0.0.0.0:*    users:(("redis-server",pid=3708413,fd=6)) 

# 方法一: kill 杀死进程
root@VM-8-10-ubuntu:~/redis# kill -9 1224091
# 方法二: shutdown 关闭
root@VM-8-10-ubuntu:~/redis# redis-cli -p 6381 shutdown

# 重新启动
root@VM-8-10-ubuntu:~/redis# redis-server ./slave1.conf
root@VM-8-10-ubuntu:~/redis# redis-server ./slave2.conf


# 查看状态
root@VM-8-10-ubuntu:/var/lib/redis# netstat -anp | grep redis
tcp        0      0 0.0.0.0:6380            0.0.0.0:*               LISTEN      1229250/redis-serve 
tcp        0      0 0.0.0.0:6381            0.0.0.0:*               LISTEN      1229260/redis-serve 
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      3708413/redis-serve 
tcp        0      0 127.0.0.1:6379          127.0.0.1:33216         ESTABLISHED 3708413/redis-serve 
tcp        0      0 127.0.0.1:33216         127.0.0.1:6379          ESTABLISHED 1229939/redis-cli   
tcp        0      0 127.0.0.1:6381          127.0.0.1:41586         ESTABLISHED 1229260/redis-serve 
tcp        0      0 127.0.0.1:41586         127.0.0.1:6381          ESTABLISHED 1229945/redis-cli   
unix  3      [ ]         STREAM     CONNECTED     22725872 3708413/redis-serve 

注意:如果是使用 service redis-server start方式启动的,就必须使用 service redis-server stop 来进行停止

  • 此时如果使用 kill的方式停止,kill 掉之后,这个 reis-server 进程能自动启动
  • 原因:往往会有另外一个进程,来专门监控指定的服务器进程的运行状态
  • 服务器就是要稳定性和高可用,但是服务器上的某些程序,可能也难以避免出现挂了的情况,如果服务器进程挂,要是能自动重启进程(把进程再启动起来),对于整体的服务不会产生严重影响

上面还可以发现,除了三个redis-server,还有很多其它的 redis 网络连接,这是因为主从之间,要进行数据传输,所以要创建额外的网络连接。

测试如下:

image-20250707164100110

  • 左侧端口为6379 主节点,右侧为6380从节点,主节点设置key1 123,从节点可以get得到,但是当从节点试图写入数据,发生报错,表示不允许修改数据。
  • 只读模式(READONLY):默认情况下,从节点配置为只读模式(slave-read-only=yes),以防止数据不一致。
info replication 节点信息查看

1)主节点信息

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=182,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=182,lag=1
master_replid:3790d18591888528a27dc7ef678aca2458709ddb
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:182
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:182
  • role:master(当前节点是主节点)

  • connected_slaves:2(当前有两个从节点连接到该主节点)

  • slave0 和 slave1 状态:

    • IP:127.0.0.1

    • Port: 分别为 6380 和 6381

    • State:online,表示从节点在线。

    • Offset:表示当前复制流的位置,两个从节点同步进度一致。

    • Lag:0,表示从节点与主节点之间没有延迟。

  • master_replid:主节点当前的复制ID

  • master_replid2:上一个复制ID,用于故障恢复或断开后重新连接时继续复制。

  • master_repl_offset:主节点已发送给从节点的数据偏移量。

  • second_repl_offset:表示在第二次复制会话开始时的偏移量。

  • repl_backlog_active: 1,复制积压缓冲区处于活动状态。

  • repl_backlog_size1048576(1MB),积压缓冲区大小

  • repl_backlog_first_byte_offset:当前积压缓冲区中第一个字节的偏移量。

  • repl_backlog_histlen: 积压缓冲区中保存的历史数据长度。

2)从节点信息

127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1751878049
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:4c19904c8341ca4df8cf851f84d5598e87cacfe4
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
  • master_xxx:主节点的一些信息
  • slave_priority:一个优先级,如果主节点崩溃了,会从新选主节点,与该优先级有关
  • master_replid:主节点的id
  • connected_slaves:表明当前节点下连接的从节点数量,若无则显示0。

这些内容也不需要记忆,可以去官网查询,官方文档【INFO | Docs】有很详细的解释。

image-20250707165641288

2. 断开主从复制

slaveof 命令不但可以建立复制,还可以在从节点执行 slaveof no one 来断开与主节点复制关系,例如在 6380 节点上执行 slaveof no one 来断开复制。

  • 效果:断开与主节点复制关系,从节点晋升为主节点。从节点断开复制后并不会抛弃原有数据,只是无法再获取主节点上的数据变化。

通过 slaveof 命令还可以实现切主操作,将当前从节点的数据源切换到另一个主节点。执行 slaveof{newMasterIp} {newMasterPort}命令即可,切主操作主要流程 如下:

  1. 断开与旧主节点复制关系。
  2. 与新主节点建立复制关系。
  3. 删除从节点当前所有数据。
  4. 从新主节点进行复制操作。

我们可以尝试来实现一下 这个“认贼作父”的过程

img

操作如下

img

3. 其他

3.1 安全性:密码认证机制

对于数据比较重要的节点,主节点会通过设置 requirepass 参数进行密码验证,这时所有的客戶端访问必须使用 auth 命令实行校验。从节点与主节点的复制连接是通过一个特殊标识的客戶端来完成,因此需要配置从节点的 masterauth 参数与主节点密码保持一致,这样从节点才可以正确地连接到主节点并发起复制流程。

3.2 只读模式:防止主从数据不一致

默认情况下,从节点使用 slave-read-only=yes 配置为只读模式。意味着:可以从从节点读取数据,但不能执行写操作(如 SET, DEL 等)。

原因:由于复制只能从主节点到从节点,对于从节点的任何修改主节点都无法感知,修改从节点会造成主从数据不一致。所以建议线上不要修改从节点的只读模式

为什么推荐开启只读?

  1. 数据一致性:如果允许从节点写入,主节点无法感知这些变化,导致主从数据不一致
  2. 应用层误操作:客户端可能误将数据写入从节点,造成混乱
  3. 脏数据传播:如果从节点写入了错误数据,可能会被误认为是合法数据
3.3 传输延迟

主从节点一般部署在不同机器上,复制时的网络延迟就成为需要考虑的问题,Redis 为我们提供了 repl-disable-tcp-nodelay 参数用于控制是否关闭 TCP NODELAY,默认为 no,即开启 tcpnodelay 功能,说明如下:(这里的目的和 Tcp 的捎带应答是一样的)

  • 一般是默认启用了 Nagle算法:旨在通过合并较小的TCP数据包来减少传输的数据包数量,从而节省带宽。然而,这可能会增加TCP的传输延迟。反之,关闭Nagle算法可以减少传输延迟但会增加网络带宽的使用。

两种模式对比

模式 特点 使用场景 类比解释
开启 Nagle(合并发送) 合并小包,节省带宽,延迟高【默认发送时间间隔取决于 Linux 的内核,一般默认为 40 毫秒】 跨机房、网络不稳定环境 公交车载满人才发车,省油(带宽),但乘客(数据)等待时间长
关闭 Nagle(及时发送) 实时发送命令(无论大小),延迟低,带宽消耗大 同城/同机房部署,要求低延迟 出租车随叫随走,快但油耗高(带宽占用大)

二、主从拓扑结构

拓扑结构:若干个节点之间,按照什么样的方式来进行组织连接

Redis 的复制拓扑结构支持单层或多层的复制关系,如下:

类型 结构图 特点
一主多从(最常见) Master → Slave1, Slave2, … 简单高效,适合读写分离
级联复制(树状结构) Master → Slave1 → Slave2 减轻主节点压力,适合大规模部署
链式复制(线性结构) Slave1 ← Slave2 ← Slave3 可控性强,但延迟可能较大
多主结构(哨兵模式/Cluster) 多个 Master + 多个 Slave 高可用架构,支持自动故障转移

1. 一主一从

一主一从结构是最简单的复制拓扑结构,用于主节点出现宕机时从节点提供故障转移支持,如图所示。当应用写命令并发量较高且需要持久化时,可以只在从节点上开启 AOF,这样既可以保证数据安全性同时也避免了持久化对主节点的性能干扰。

img

注意:这种方式要 关闭主节点的自动重启功能,因为主节点使用RDB持久化,此时数据往往不是最新的。一旦主节点重启,那么就会通过RDB恢复数据,导致主节点得到旧数据。而这个旧数据又会同步给从节点,此时从节点的AOF新数据就被旧数据覆盖了

2. 一主多从

一主多从结构(星形结构)使得应用端可以利用多个从节点实现读写分离,如图所示。

image-20250707180115367

  • 适用场景:适用于读数据比重较大的场景(如:缓存服务),可以将 读命令负载均衡 到不同的从节点上来分担压力,同时一些耗时的读命令可以指定一台专门的从节点执行,避免破坏整体的稳定性。

  • 缺点

    • 不适用于写数据比重较大的场景,因为随着从节点个数增加,主节点的网络传输压力也会增大
    • 主节点宕机后整个系统不可写(需配合哨兵或 Cluster 使用)

3. 级联复制(树状结构)

树形主从结构(分层结构)使得 从节点 不但可以复制 主节点 数据,同时可以作为其他 从节点 的 主节点 继续向下层复制。通过引入复制中间层,可以有效降低住系按负载和需要传送给从节点 的数据量,如图所示。

  • 数据写入 节点A之后会同步给 B和 C节点,B节点 进一步把数据同步给 D 和 E节点。
  • 主节点 需要挂载等多个 从节点 时为了避免对 主节点 的性能干扰,可以采用这种拓扑结构。

img

  • 特点:从节点不仅可以复制主节点数据,还可以作为其他从节点的主节点继续向下层复制。

  • 优势

    • 相比一主多从结构,可以减少主节点网络传输压力,不需要那么高的网卡带宽
    • 配置稍复杂,需确保每一层正确同步
  • 缺点

    • 数据同步存在层级延迟(Slave2 的数据滞后于 Slave1 和 Master)

    • 配置稍复杂,需确保每一层正确同步

4. 链式复制结构(Chain Replication)

Slave1 ← Slave2 ← Slave3

🧩特点

  • 从节点之间形成一条链,每个节点既是前一个的从节点,又是下一个的主节点
  • 通常用于边缘计算、远程节点数据聚合等场景

优点

  • 每个节点只需与上一级通信,减少对中心节点依赖
  • 节省带宽,适合低速网络环境

⚠️ 缺点

  • 数据更新延迟大
  • 故障传播风险:某个节点异常可能导致后续节点数据异常🧩

4. 多主多从结构(用于哨兵或 Cluster)

Master1 ↔ Sentinel1
   │
Slave1
Master2 ↔ Sentinel2
   │
Slave2

特点

  • 每个主节点有自己的从节点
  • 配合哨兵(Sentinel)实现自动故障转移
  • 或者使用 Cluster 分片方式实现数据分布

优点:高可用(主节点故障时可切换)、支持横向扩展(scale-out)

缺点:配置复杂、需要额外组件(如 Sentinel、Proxy、Cluster 模式)

三、主从复制原理

1. 复制过程

如图所示,下面详细介绍建立复制的完整流程。从图中可以看出复制过程大致分为6个过程:

img

保存信息:首先保存主节点的信息,包括IP和端口。如下:

master_host: 127.0.0.1
master_port: 6379
master_link_status: down
  • 从统计信息可以看出,主节点的 ip 和 port 被保存下来,但是主节点的连接状态(master_link_status)是下线状态

建立连接:建立主从节点之间的TCP连接(经历三次握手,系统层面)

  • 从节点(slave)内部通过 每秒运行的定时任务维护复制相关逻辑,当定时任务发现存在新的主节点后,会尝试与主节点建立基于 TCP 的网络连接
  • 如果从节点无法建立连接,定时任务会 无限重试直到连接成功 或者 用户停止主从复制

验证连接:给主节点发送PING命令,验证其是否正常工作(应用程序角度)

  • 连接建立成功之后,从节点通过 ping 命令确认主节点在应用层上是工作良好的。
  • 如果 ping 命令的结果 pong 回复超时,从节点会断开 TCP 连接,等待定时任务下次重新建立连接

权限验证:密码验证

  • 如果主节点设置了 requirepass 参数,则需要密码验证,从节点通过配置 masterauth 参数来设置密码
  • 如果验证失败,则从节点的复制将会停止

数据同步:包括全量同步(首次连接时同步所有数据)和 命令持续复制(增量同步,后续每一步操作都进行同步)

在整个主从同步的过程中,最后两步分别是 同步数据集和持续复制命令,是复制数据的关键步骤

  • 同步数据集
    • 如果是第一次同步,触发 全量同步,这步操作是耗时最长的
    • 如果是断线重连,触发 部分同步
  • 持续复制命令:进行 实时同步。当从节点复制了主节点的所有数据之后,针对之后的修改命令,主节点会持续的把命令发送给从节点,从节点执行修改命令,保证主从数据的一致性。

2. 数据同步(PSYNC)

Redis 提供了 PSYNC 命令来完成数据同步的过程。PSYNC 指令一般不需要我们手动执行,Redis 服务器会在建立好主从同步关系之后自动执行 PSYNC。

其语法格式为 PSYNC replicationid offset

  • replidoffset 共同确定一个唯一的数据集

replicationid(主节点复制 ID)

  • 这个ID是主节点启动时生成的,每次主节点重启后生成的 replicationid 都是不一样的。或者是在从节点和主节点断开之后,从节点晋升为主节点时也会生成新的 replicationid。
  • 这个参数实际上就是我们之前通过 info replication 查询出来的 master_replid。一旦从节点与主节点建立了复制关系,它就会从主节点这边获取到 replicationid。

举个例子:还记得上面我演示的 关于 master_replid 和 master_replid2

master_replid:3790d18591888528a27dc7ef678aca2458709ddb
master_replid2:0000000000000000000000000000000000000000

每个节点需要记录两组 master_replid,这个设定解决的问题场景是这样的:

比如当前有两个节点 A 和 B,A为 master、B 为 slave,此时 B 就会记录 A 的 master_replid

  • 如果网络出现抖动,B 以为 A挂了,B 自己就会成为主节点,于是 B 给自己分配了新的 master_replid。此时就会使用 master replid2 来保存之前 A的 master replid.
  • 后续如果网络恢复了,B 就可以根据 master_replid2 找回之前的主节点。
  • 后续如果网络没有恢复。B 就按照新的 master_replid 自成一派,继续处理后续的数据

offset(复制偏移量)

  • 这个参数是主节点和从节点上都会维护的数据偏移量,它是一个整数(统计信息在 inforeplication 中 的 **_repl_offset 指标中,我们可以通过对比主从节点的复制偏移量是否相等来判断主从节点数据是否⼀致
  • 主节点上会收到很多修改操作的命令,每个命令都要占据一定的字节数。主节点会把这些修改命令中的数据的字节数进行累加,得到主节点的 offset
  • 从节点的偏移量描述的是 当前从节点在从主节点同步数据时同步到了哪里。从节点每秒钟都会上报自身的复制偏移量给主节点。

关于 PSYNC 的工作方式:

img

  • PSYNC 可以从主节点中获取全量数据,也可以获取一部分数据,这主要取决于 offset 的进度。如果 offset 设置为 -1,则表示获取全量数据;如果 offset 设置为具体的整数值,则表示从当前的偏移量开始进行获取。

当输入psync后,可能得到以下三种结果:

  1. +FULLRSYNC replid offset:进行全量复制
  2. +CONTINUE:进行部分复制
  3. -ERR:说明主节点不支持psync,此时可以使用 sync
    • 此处sync是在前台运行的命令,一旦执行 sync,主节点的所有命令都会被阻塞。

注意:在获取数据时,并不是从节点请求哪部分数据,主节点就提供哪部分数据。

  1. 主节点会自行判定当前是否方便提供部分数据,若不方便,则只能提供 全量数据
  2. 从节点申请进行全量复制,此时主节点无法承受这么多网络压力,那么可能就会变成 部分复制

3. 三种复制方式

3.1 全量复制

触发条件:首次与主节点进行数据同步时,或在主节点不方便进行部分复制的情况下,从节点会进行全量复制。此时的 replicationidoffset 分别是未知和 -1

img

  1. 发起同步:从节点发送 PSYNC 命令给主节点进行数据同步,由于初次复制,从节点没有主节点的运行ID和offset,因此默认执行全量复制。
  2. 响应确认:主节点根据命令解析出要进行全量复制,并回复 +FULLRESYNC 响应。
  3. 保存信息:从节点接收并 保存主节点的运行信息(eg. id…)
  4. 持久化快照:主节点执行 BGSAVE 进行 RDB 文件的持久化。
  5. 传输快照:主节点将生成的 RDB 文件发送给从节点,从节点保存该文件到本地磁盘。
  6. 补发增量:主节点将从生成 RDB 文件到接收完成期间执行的写命令的数据写入缓冲区,等从节点保存完 RDB 文件之后,再将缓冲区内的数据补发。
  7. 清理旧数据:从节点清空自身原有的旧数据。
  8. 加载新数据:从节点 加载 RDB 文件以获得与主节点一致的数据。(5+6)
  9. 持久化操作:如果从节点开启了 AOF 持久化,则会进行重写操作;如果没有开启,则全量化复制完成。

无硬盘模式支持

  • 主节点在进行全量复制时也支持“无硬盘模式”,即主节点生成的 RDB 二进制数据直接通过网络传输给从节点,无需先保存到文件中。
  • 从节点也可以省略把收到的数据写入硬盘的过程,直接加载。这虽然节省了读写硬盘的操作,但网络传输消耗不可避免。
3.2 部分复制

适用场景:当从节点已经持有主节点绝大部分的数据时,为了减少开销,可以进行部分复制。例如在网络抖动后重新建立连接时,只需同步中断期间的数据变化即可。

流程图

img

  1. 超时判定:当主节点和从节点出现网络中断超过 repl-timeout 时间,主节点会认为从节点故障。
  2. 命令滞留:中断期间,主节点继续响应命令,但由于网络问题无法及时发送给从节点,这些命令被暂时滞留在 积压缓冲区。
  3. 主节点与从结点网络恢复.
  4. 从节点将之前保存的 replicationidoffset 作为 PSYNC 参数发送给主节点,请求部分复制。
  5. 验证与查找:主节点接收到 PSYNC 请求后,进行必要的验证,随后根据offset区复制积压缓冲区查找合适的数据,并响应+CONTINUE给从节点.
  6. 数据同步:主节点将所需同步的数据发送给从节点,最终完成一致性。

在第5步的时候,验证的步骤具体是什么呢? [ 这里是一个非常经典的验证思想 ]

  • 首先验证 replicationid 是否一致。如果不一致,则进行全量复制;
  • 如果一致,则进一步判断 offset 是否存在于积压缓冲区中。若存在,则可以进行部分复制;否则需要全量复制。
3.3 实时复制

描述:主从节点在建立复制连接后,主节点会把自己收到的修改操作,通过 TCP 长连接的方式,源源不断的传输给从节点,从节点就会根据这些请求来同时修改自身的数据,保持从节点和主节点数据的一致性。

  • 机制:从节点和主节点之间维持一个TCP长连接,主节点通过此连接将收到的修改数据请求发送给从节点。为确保网络连接可用,引入了 心跳包机制—— 主节点 每隔10秒 给从节点发送一个 PING 命令,从节点接收到后返回 PONG;同时,从节点每秒向主节点上报当前复制进度(offset)

如果主节点发现从节点通信延迟超过 repl-timeout 配置的值(默认60秒),则判定从节点下线,断开复制客户端连接。从节点恢复连接后,心跳机制继续进行。

四、小结

单点问题

  • 单个 Redis 节点, 可用性不高.
  • 单个 Redis 节点, 性能有限.

主从复制的特点:

  • Redis 通过复制功能实现主节点的多个副本。
  • 主节点用来写,从节点用来读. 这样做可以降低主节点的访问压力
  • 复制支持多种拓扑结构,可以在适当的场景选择合适的拓扑结构。
    • 复制分为 全量复制 , 部分复制 和 实时复制
    • 全量复制 , 部分复制 都是从节点刚连上主节点触发的(初始化部分)
  • 主从节点之间通过 心跳机制 保证主从节点通信正常和数据⼀致性。

主从复制配置的过程

  • 主节点配置不需要改动.
  • 从节点在配置文件中加入 slaveof [主节点 ip] [主节点端口] 的形式即可.

主从复制存在的问题

  1. 从机多了, 复制数据的延时非常明显.
  2. 主机挂了,从机不会升级成主机. 只能通过人工干预的方式恢复

🔥 最大的问题在于主节点上。如果主节点意外 宕机(如:主节点挂了),从节点虽能继续提供读操作,但不会自动升级为主节点(除非通过 SLAVEOF NO ONE 断开)。这时就需要程序员手动恢复主节点,或者引入哨兵模式来实现自动故障转移(对挂了主节点进行替换)

★,°:.☆( ̄▽ ̄)/$:.°★ 】那么本篇到此就结束啦,如果有不懂 和 发现问题的小伙伴可以在评论区说出来哦,同时我还会继续更新关于【Redis】的内容,请持续关注我 !!

在这里插入图片描述

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐