【Redis】Redis 集群中节点之间如何通信?

【Redis】Redis 集群中节点之间如何通信?

一·背景概述

Redis集群中节点间通信是指Redis集群中的各个节点通过一定的协议和机制相互传递信息,以实现集群的协调、数据同步、故障检测等功能。

在分布式系统中,不同的节点进行数据/信息共享是一个基本的需求。一种比较简单粗暴的方法就是 集中式发散消息,简单来说就是一个主节点同时共享最新信息给其他所有节点,比较适合中心化系统。这种方法的缺陷也很明显,节点多的时候不光同步消息的效率低,还太依赖与中心节点,存在单点风险问题。

二·通信协议

于是,分散式发散消息 的 Gossip 协议 就诞生了。

Gossip 协议

也叫 Epidemic 协议(流行病协议)或者 Epidemic propagation 算法(疫情传播算法),别名很多。

显而易见,最大的特点都具有 随机传播特性

在 Gossip 协议下,没有所谓的中心节点,每个节点周期性地随机找一个节点互相同步彼此的信息,理论上来说,各个节点的状态最终会保持一致。

下面我们来对 Gossip 协议的定义做一个总结:

Gossip协议是一种分布式系统中常用的通信协议,它具有去中心化、容错性强、扩展性好等特点。在Redis集群中,每个节点都会定期向其他节点发送消息,这些消息包含了节点的状态信息、集群的拓扑结构信息等。节点接收到消息后,会根据消息内容更新自己的状态,并将更新后的信息传播给其他节点。通过这种方式,集群中的所有节点最终都会拥有完整的集群信息。

三·通信机制

Redis 的官方集群解决方案Redis Cluster 是一个典型的分布式系统,分布式系统中的各个节点需要互相通信。既然要相互通信就要遵循一致的通信协议,Redis Cluster 中的各个节点基于 Gossip 协议 来进行通信共享信息,每个 Redis 节点都维护了一份集群的状态信息。而每个Redis Cluster 的节点之间会相互发送多种 Gossip 消息:

Gossip 消息类型

(1).Ping消息

用于检测节点是否在线和运行正常。每个节点都会定期向其他节点发送ping消息,收到ping消息的节点会回复pong消息以确认通信正常。Redis Cluster 中的节点都会定时地向其他节点发送 PING 消息,来交换各个节点状态信息,检查各个节点状态,包括在线状态、疑似下线状态 PFAIL 和已下线状态 FAIL。

(2).Pong消息

作为对ping消息的响应,pong消息还包含了节点的当前状态信息,可以用于更新其他节点的状态。

(3).Meet消息

用于通知新节点加入集群。当一个新节点加入集群时,集群中的某个节点会向新节点发送meet消息,新节点收到消息后会开始与其他节点进行通信。在 Redis Cluster 中的某个 Redis 节点上执行 CLUSTER MEET ip port 命令,可以向指定的 Redis 节点发送一条 MEET 信息,用于将其添加进 Redis Cluster 成为新的 Redis 节点。

(4).Fail消息

用于通知集群中的其他节点某个节点已经下线。当一个节点判定另一个节点故障时,它会向集群内广播一个fail消息,其他节点接收到fail消息后会把对应节点更新为下线状态。Redis Cluster 中的节点 A 发现 B 节点 PFAIL ,并且在下线报告的有效期限内集群中半数以上的节点将 B 节点标记为 PFAIL,节点 A 就会向集群广播一条 FAIL 消息,通知其他节点将故障节点 B 标记为 FAIL 。

消息传播模式

Gossip 协议消息传播模式Gossip 设计了两种可能的消息传播模式:反熵(Anti-Entropy) 和 传谣(Rumor-Mongering)。

(1).反熵(Anti-entropy)

根据维基百科:熵的概念最早起源于物理学,用于度量一个热力学系统的混乱程度。熵最好理解为不确定性的量度而不是确定性的量度,因为越随机的信源的熵越大

在这里,你可以把反熵中的熵理解为节点之间数据的混乱程度/差异性,反熵就是指消除不同节点中数据的差异,提升节点间数据的相似度,从而降低熵值。

具体是如何反熵的呢?集群中的节点,每隔段时间就随机选择某个其他节点,然后通过互相交换自己的所有数据来消除两者之间的差异,实现数据的最终一致性。

在实现反熵的时候,主要有推、拉和推拉三种方式:

  • 推方式:就是将自己的所有副本数据,推给对方,修复对方副本中的熵。
  • 拉方式:就是拉取对方的所有副本数据,修复自己副本中的熵。
  • 推拉:就是同时修复自己副本和对方副本中的熵。

反熵伪代码在我们实际应用场景中,一般不会采用随机的节点进行反熵,而是可以设计成一个闭环。这样的话,我们能够在一个确定的时间范围内实现各个节点数据的最终一致性,而不是基于随机的概率。

(2).谣言传播(Rumor mongering)

谣言传播指的是分布式系统中的一个节点一旦有了新数据之后,就会变为活跃节点,活跃节点会周期性地联系其他节点向其发送新数据,直到所有的节点都存储了该新数据。谣言传播比较适合节点数量比较多的情况,不过,这种模式下要尽量避免传播的信息包不能太大,避免网络消耗太大。

为了给大家说清楚这两种传播模式,列了下表:

四·通信过程

通信端口

Redis集群中的每个节点都有一个专门用于节点间通信的端口号,这个端口号通常是节点提供服务的端口号加上一个固定的偏移量(如10000)。例如,如果节点的服务端口号是6379,那么用于通信的端口号就是16379。

通信频率

Redis集群中的节点通信频率是可配置的。每个节点都会维护一个定时任务,该任务会按照指定的频率(如每秒执行若干次)选择其他节点发送消息。通过调整通信频率,可以在集群的稳定性和通信开销之间取得平衡。

故障检测与恢复

Redis集群通过Gossip协议和一致性算法共同实现故障检测。当一个节点判定另一个节点故障时,它会向集群内广播fail消息。其他节点接收到fail消息后,会根据一定的规则(如多数派原则)来判断该节点是否真的故障,并更新集群的状态。如果某个节点被判定为故障节点,集群会触发故障恢复机制,如重新分配槽位、选举新的主节点等。

下图就是主从架构的 Redis Cluster 的示意图

有了 Redis Cluster 之后,不需要专门部署 Sentinel 集群服务了。Redis Cluster 相当于是内置了 Sentinel 机制,Redis Cluster 内部的各个 Redis 节点通过 Gossip 协议共享集群内信息。

通信示例

假设Redis集群中有三个节点A、B、C,它们之间的通信过程可能如下:

  • 节点A定期向节点B和节点C发送ping消息,以检测它们是否在线。
  • 节点B和节点C收到ping消息后,回复pong消息给节点A,并附带自己的状态信息。
  • 如果节点A判定节点C故障(例如,长时间未收到节点C的pong消息),它会向集群内广播一个fail消息。
  • 节点B收到fail消息后,根据多数派原则判断节点C是否真的故障,并更新集群的状态。
  • 如果节点C确实故障,集群会触发故障恢复机制,如重新分配节点C负责的槽位到其他节点上。

节点 A 推送数据给节点 B,节点 B 获取到节点 A 中的最新数据。节点 B 推送数据给 C,节点 C 获取到节点 A,B 中的最新数据。节点 C 推送数据给 A,节点 A 获取到节点 B,C 中的最新数据。节点 A 再推送数据给 B 形成闭环,这样节点 B 就获取到节点 C 中的最新数据。

虽然反熵很简单实用,但是,节点过多或者节点动态变化的话,反熵就不太适用了。这个时候,我们想要实现最终一致性就要靠 谣言传播(Rumor mongering) 。

五·总结

Gossip协议优势

1、相比于其他分布式协议/算法来说,Gossip 协议理解起来非常简单。

2、能够容忍网络上节点的随意地增加或者减少,宕机或者重启,因为 Gossip 协议下这些节点都是平等的,去中心化的。新增加或者重启的节点在理想情况下最终是一定会和其他节点的状态达到一致。

3、速度相对较快。节点数量比较多的情况下,扩散速度比一个主节点向其他节点传播信息要更快(多播)。

Gossip协议缺陷

1、消息需要通过多个传播的轮次才能传播到整个网络中,因此,必然会出现各节点状态不一致的情况。毕竟,Gossip 协议强调的是最终一致,至于达到各个节点的状态一致需要多长时间,谁也无从得知。

2、由于拜占庭将军问题,不允许存在恶意节点。

3、可能会出现消息冗余的问题。由于消息传播的随机性,同一个节点可能会重复收到相同的消息。

我是杰叔叔,一名沪漂的码农,下期再会!

相关推荐
TiDB_PingCAP5 分钟前
唐刘:TiDB 的 2024 - Cloud、SaaS 与 AI
数据库·人工智能·ai·tidb·saas
yuanpan1 小时前
MongoDB中游标的使用
数据库·mongodb
我是單身你是狗1 小时前
Jmeter数据库
数据库·jmeter
数巨小码人2 小时前
PostgreSQL-WAL日志介绍(二)
数据库·postgresql
丁总学Java2 小时前
在 macOS 上,用命令行连接 MySQL(/usr/local/mysql/bin/mysql -u root -p)
数据库·mysql·macos
FUXI_Willard2 小时前
Chapter1:初见C#
开发语言·数据库·c#
九河云5 小时前
阿里云数据传输服务使用场景
数据库·阿里云·云计算
_.Switch5 小时前
高效构建与部署Python Web应用:FastAPI的测试与持续集成
前端·网络·数据库·python·ci/cd·fastapi
不烦下雨c6 小时前
【Mysql进阶知识】Mysql 程序的介绍、选项在命令行配置文件的使用、选项在配置文件中的语法
数据库·mysql
Kendra9196 小时前
数据库(MySQL)练习
数据库·mysql