Redis中的集群(十)

集群

FAIL消息的实现

当集群里的主节点A将主节点B标记为已下线(FAIL)时,主节点A将向集群广播一条关于主节点B的FAIL消息,所有接收到这条FAIL消息的节点都会将主节点B标记为已下线。在集群的节点数量比较大的情况下,单纯使用Gossip协议来传播节点的已下线信息会给节点的信息更新带来一定延迟,因为Gossip协议消息通常许需要一段时间才能传播至整个集群,而发送FAIL消息可以让集群里的所有节点立即知道某个主节点已下线,从而尽快判断是否需要将集群标记为下线,又或者对下线主节点进行故障转移。FAIL消息的正文由cluster.h/clusterMsgDataFail结构表示,这个结构只包含一个nodename属性,该属性记录了已下线节点的名字:

typedef struct {
	char nodename[REDIS_CLUSTER_NAMELEN];
}clusterMsgDataFail;

因为集群里的所有节点都有一个独一无二的名字,所以FAIL消息里面只需要保存下线节点的名字,接收到消息的节点就可以根据这个名字来判断是哪个节点下线了。

例子

  • 举个例子。对于包含7000、7001、7002、7003四个主节点的集群来说:
    1.如果主节点7001发现主节点7000已下线,那么主节点7001将向主节点7002和主节点7003发送FAIL消息,其中FAIL消息中包含的节点名字为主节点7000的名字,以此来表示主节点7000已下线
    2.当主节点7002和主节点7003都接收到主节点7001发送的FAIL消息时,它们也会将主节点7000标记为已下线
    3.因为这时集群已经有超过一半的主节点认为主节点7000已下线,所以集群剩下的几个主节点可以判断是否需要将集群标记为下线,又或者开始对主节点7000进行故障转移

图中展示了节点发送和接收FAIL消息的整个过程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

PUBLISH消息的实现

当客户端向集群中的某个节点发送命令:

PUBLISH <channel> <message>

的时候,接收到PUBLISH命令的节点不仅会向channel频道发送消息message,他还会向集群广播一条PUBLISH消息,所有接收到这条PUBLISH消息的节点都会向channel频道发送message消息。换句话说,向集群中的某个节点发送命令:

PUBLISH <channel> <message>

PUBLISH消息的正文由cluster.h/clusterMsgDataPublish结构表示:

typedef struct {
uint32_t channel_len;
uint32_t message_len;

// 定义为8字节只是为了对齐其他消息结构
// 实际的长度由保存的内容决定
unsigned char bulk_data[8];
}clusterMsgDataPublish;

clusterMsgDataPublish结构的bulk_data属性是一个字节数组,这个字节数组保存了客户端通过PUBLISH命令发送给节点的channel参数和message参数,而结构的channel_len和message_len则分别保存channel参数的长度和message参数的长度:

  • 1.其中bulk_data的0字节至channel_len -1字节保存的是channel参数
  • 2.而bulk_data的channel_len字节至channel_len + message_len - 1字节保存的则是message参数

例子

  • 举个例子。对于包含7000、7001、7002、7003四个节点的集群来说,如果节点7000收到了客户端发送的PUBLISH命令,那么节点7000将向7001、7002、7003三个节点发送PUBLISH消息,如图所示
    在这里插入图片描述
  • 举个例子。如果节点收到的PUBLISH命令为:
PUBLISH "news.it" "hello"

那么节点发送的PUBLISH消息的clusterMsgDataPublish结构将如图所示:
其中bulk_data数组的前七个字节保存了channel参数的值"news.it"而bulk_data数组的后五个字节则保存了message参数的值"hello"
在这里插入图片描述

为什么不直接向节点广播PUBLISH命令?

实际上,要让集群的所有节点都执行相同的PUBLISH命令,最简单的方法就是向所有节点广播相同的PUBLISH命令,这也是Redis在复制PUBLISH命令时所使用的方法,不过因为这种做法并不符合Redis集群的"各个节点通过发送和接收消息来进行通信"这一规则,所以节点没有采取广播PUBLISH命令的做法

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-15 08:22:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-15 08:22:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-15 08:22:02       87 阅读
  4. Python语言-面向对象

    2024-04-15 08:22:02       96 阅读

热门阅读

  1. vue3+ts实现表格单元格编辑功能

    2024-04-15 08:22:02       28 阅读
  2. 关于分布式session的问题

    2024-04-15 08:22:02       23 阅读
  3. TLC3702双微功耗电压比较器

    2024-04-15 08:22:02       40 阅读
  4. HTTP 响应码

    2024-04-15 08:22:02       29 阅读
  5. Vue中key的作用和原理

    2024-04-15 08:22:02       97 阅读
  6. Node.js环境WebSocket示例

    2024-04-15 08:22:02       38 阅读
  7. 顺序表原码(练习版)

    2024-04-15 08:22:02       37 阅读
  8. ES6 的解构赋值

    2024-04-15 08:22:02       41 阅读
  9. 浏览器从输入url到渲染的过程

    2024-04-15 08:22:02       36 阅读
  10. CentOS 设置静态 IP 配置

    2024-04-15 08:22:02       129 阅读