文章目录
- [1. 引入](#1. 引入)
- [2. 主从复制模式](#2. 主从复制模式)
-
- [2.1 概念](#2.1 概念)
- [2.2 配置](#2.2 配置)
- [2.3 原理](#2.3 原理)
-
- [2.3.1 建立连接阶段](#2.3.1 建立连接阶段)
- [2.3.2 命令传播阶段](#2.3.2 命令传播阶段)
- [2.3.3 心跳检测机制](#2.3.3 心跳检测机制)
- [2.3.4 部分重同步机制](#2.3.4 部分重同步机制)
-
- [(1) 主节点通过 复制积压缓冲区 记录写命令](#(1) 主节点通过 复制积压缓冲区 记录写命令)
- [(2) 主节点通过 复制偏移量 判断从节点是否满足执行部分重同步的条件](#(2) 主节点通过 复制偏移量 判断从节点是否满足执行部分重同步的条件)
- [(3) 执行部分重同步操作](#(3) 执行部分重同步操作)
- [2.4 优点](#2.4 优点)
- [2.5 缺点](#2.5 缺点)
- [3. 总结](#3. 总结)
1. 引入
随着使用互联网的人数的增多,服务器每秒能处理的请求数量也需要不断增加。为此,传统的单体系统架构变成了分布式的系统架构,单体的中间件变成了中间件的集群。像 MySQL 主从复制的集群模式经常在网络上见到,Redis 也有自己的集群模式,主要分为三种:
- 主从复制模式。
- 哨兵模式。
- 分片集群。
本文主要讲解第一种模式,第二种和第三种模式将会分成两篇文章在之后讲解。
2. 主从复制模式
2.1 概念
在 Redis 集群中,将 Redis 节点分成两种节点------一个主节点 和 多个从节点,规则如下:
- 主节点处理写操作。
- 从节点处理读操作。
- 主节点处理完写操作后,将写操作 异步 发送给所有从节点,从节点接收并执行写操作,以保证主从数据一致。
Redis 主从复制模式的集群形成的结构图如下所示:
Redis 集群 同步数据 同步数据 同步数据 同步数据 从节点1 主节点 从节点2 从节点 ... 从节点 n 写操作 读操作
通过这种集群模式,得以将读操作和写操作分离,并且把读操作分散到多台 Redis 上,很大程度上增加了每秒处理查询请求的数量。
2.2 配置
对于 Redis 的主从复制模式,无需对主节点配置任何多余信息,主要配置从节点的 redis.conf
文件:
slaveof <master-ip> <master-port>
:在<master-ip>
处填写主节点的 ip 地址,<master-port>
填写主节点 Redis 对外开放的端口号。这个配置让 从节点 知道要从哪个 主节点 进行复制。masterauth <master-requirepass>
:如果主节点设置了密码,在<master-requirepass>
处填写对应的密码,用于从服务器连接主服务器时的身份验证。
如下配置可以作为 Redis 从节点中 配置主节点信息 的参考:
conf
slaveof 192.168.100.1 6379
masterauth e0cfd72aa80e
如下配置是 Redis 主节点 配置密码信息 的参考:
conf
requirepass e0cfd72aa80e
2.3 原理
2.3.1 建立连接阶段
- 从节点发起同步请求 :从节点启动后,会向
redis.conf
配置中指定的主节点发送SYNC
命令,请求数据同步,开启主从复制流程。 - 主节点响应并准备数据 :主节点执行
BGSAVE
命令,在后台生成当前数据集对应的 RDB 文件 (在 Redis------持久化 中讲解过 RDB)。- 在
BGSAVE
执行期间,主节点可以继续正常处理客户端发来的写请求,不过这些写请求对应的写命令会被暂存到 复制缓冲区 (replication buffer) 中。 - 当
BGSAVE
命令执行完成,生成 RDB 文件后,主节点把这个 RDB 文件发送给从节点。
- 在
- 从节点接收并载入数据 :从节点接收到主节点发来的 RDB 文件后,使用 RDB 文件,将自身的数据状态恢复到和主节点执行
BGSAVE
命令时基本一致的状态。 - 从节点同步产生 RDB 文件期间的数据 :将 RDB 文件发送给从节点后,主节点会接着把 复制缓冲区 中暂存的写命令按顺序发送给从节点,从节点再依次执行这些写命令,从而保证从节点的数据状态能和主节点完成
BGSAVE
操作时的状态一致。
流程图如下:
客户端 主节点 从节点 发起同步请求 执行 BGSAVE 指令,在后台生成 RDB 文件 许多写操作 在执行 BGSAVE 指令期间, 将写操作的写指令暂存到复制缓冲区中 当生成 RDB 文件后, 将 RDB 文件发给从节点 将数据同步到主节点执行 BGSAVE 前的状态 将复制缓冲区的写指令按顺序发给从节点 将数据同步到主节点执行 BGSAVE 后的状态 客户端 主节点 从节点
2.3.2 命令传播阶段
- 主节点发送写命令 :在完成从节点的数据同步后,只要主节点后续接收到客户端的写请求并执行完毕,它就会:
- 首先,将写命令记录到 复制积压缓冲区 (之后会详细讲解) 中。
- 然后,将其以异步的方式发送给所有已经连接的从节点。
- 从节点执行写命令:从节点接收到主节点发来的写命令后,会按照接收到的顺序依次执行这些写命令。通过不断执行主节点传来的写命令,就能时刻保证主从数据一致。
流程图如下:
客户端 主节点 从节点 写操作 执行写命令 将写命令记录到复制积压缓冲区中, 并增加自己的复制偏移量 将写命令异步发给从节点 执行主节点发送的写命令, 并增加自己的复制偏移量 客户端 主节点 从节点
2.3.3 心跳检测机制
在主从复制的整个过程中,主从节点之间还存在 心跳检测机制 来确保连接的正常和数据的及时同步:
- 从节点会定期向主节点发送
REPLCONF ACK <replication_offset>
命令 (其中<replication_offset>
表示从节点复制的偏移量,之后会详细讲解),如同 心跳 一样。发送这条信息有两个作用:- 让主节点知道自己处于正常连接状态。
- 让主节点知道自己复制的位置,从而判断自己是否需要 部分重同步 (之后会详细讲解)。
- 主节点根据从节点发来的心跳信息,可以判断从节点的连接情况。如果发现某个从节点长时间没有发送心跳,就可以标记从节点状态为下线,之后就不用再向它发送写指令了。
2.3.4 部分重同步机制
(1) 主节点通过 复制积压缓冲区 记录写命令
主节点在执行完写命令后,会将写命令缓存到 复制积压缓冲区 (replication backlog buffer) 中,这个缓冲区是 先进先出 的,和 队列 一样,目的就是 当从节点由于某些原因 (如网络暂停中断) 与主节点断开连接,又重新连接后,从节点能够通过这些写命令来实现部分重同步,避免进行完整的同步流程。
(2) 主节点通过 复制偏移量 判断从节点是否满足执行部分重同步的条件
在心跳检测时,如果主节点发现从节点的 replication_offset
(复制偏移量) 与自身的 replication_offset
相差很多,这时主节点会首先 判断从节点所缺失的那部分写命令是否还保留在复制积压缓冲区中,如果在,则可以进行部分重同步;否则从节点需要发起完整的同步流程。
(3) 执行部分重同步操作
如果确定可以进行部分重同步,主节点会根据从节点当前的 replication_offset
,从复制积压缓冲区中提取出从该偏移量之后的写命令,然后将这些写命令发送给从节点。
从节点接收到主节点发来的这些写命令后,会按照顺序依次执行,执行完后自身的 replication_offset
就会更新,从而跟上主节点的数据同步进度,完成部分重同步过程,使得主从节点的数据再次保持一致,而无需重新进行完整的初始同步 (也就是无需再执行 SYNC
命令去获取 RDB 文件等一系列操作)。
2.4 优点
- 提升读性能 :适用于 读多写少 的业务场景。在这种模式下,可以将大量的读请求分配到多个从节点上处理,分担主节点的读负载,使得系统整体能够同时处理更多的请求,提升响应速度和吞吐量。
- 数据冗余与高可用性:通过将数据从主节点复制到多个从节点,实现了数据的冗余备份。若主节点出现故障 (如硬件故障、软件崩溃、网络问题等),可以迅速将某个从节点提升为主节点,继续对外提供服务,减少因主节点故障导致的数据丢失和服务中断风险,在一定程度上保证 Redis 集群的高可用性。
- 方便数据备份与恢复:从节点本身就是主节点数据的副本,相当于自动完成了数据备份工作。在需要恢复数据时,只要从节点的数据状态是可用且完整的,就可以较为方便地利用从节点的数据来进行恢复操作,无需额外复杂的备份流程和工具。
2.5 缺点
- 数据同步延迟:在主节点执行写操作后,数据同步到从节点不是立刻完成的,存在一定的时间延迟。尤其是在高并发写场景下,延迟可能会更加明显,这就可能导致从节点的数据在短期内并非是最新的,出现主从数据不一致的情况,影响业务逻辑的准确性。
- 故障切换复杂:当主节点发生故障时,虽然理论上可以将从节点提升为主节点来继续服务,但在实际操作中,这个故障切换过程并非完全自动和简单。需要人工介入或者借助额外的监控和管理工具来准确判断主节点故障情况,合理选择要升级的从节点,并完成相关配置的调整 (如通知其他从节点新的主节点信息等),否则容易出现各种问题,导致服务中断或者数据不一致等情况。
3. 总结
通过 Redis 的主从复制模式,读操作得以和写操作分离:
- 写操作全部在在主节点上执行,主节点通过传播这些写命令,使得主从数据保持同步。
- 读操作分散到各个从节点上。
除此之外,主从复制模式还通过 心跳检测机制 和 部分重同步机制 保证主从数据的一致性。
通过主从复制模式,增强了 Redis 集群读写操作的吞吐量,并在一定程度上保证了 Redis 集群的高可用性。但是,主从节点之间的数据同步存在延迟,可能导致短暂的数据不一致情况;在主节点故障时,还得运维人员手动选出一个新的主节点并重新配置其它从节点,故障切换比较复杂。