《Redis设计与实现》读书笔记(三十一) ——Redis集群消息类型

《Redis设计与实现》读书笔记(三十一) ——Redis集群消息类型

(原创内容,转载请注明来源,谢谢)

1、发送消息类型

集群中节点通过发送与接收消息进行通信。

发送消息的节点称为消息发送者,接收消息节点称为接收者。消息发送类型如下:

1)meet

当客户端发送clustermeet给节点,节点会发送meet消息给接收者,请求接收者加入到发送者当前的集群中。

2)ping

每个节点每秒,默认会随机从当前已知节点列表,挑选5个节点,并从中挑选最久未发送过ping消息的节点,对其发送ping,检测其是否在线。

另外,如果某个节点最后一次回复pong的时间,距离当前时间,已经超过redis配置文件中cluster-node-timeout设定的秒数的一半,则也会对该节点发送ping,防止多次没有随机到该节点,导致对该节点的状态更新过慢。

3)pong

当节点收到meet或者ping,为了告知发送者收到消息,会回复pong。

另外,完成一次故障转移后,新的主节点会给向集群广播pong。

4)fail

当节点认为某个节点下线,会向集群广播关于该节点的fail状态,其他节点接收到后,都会将该节点状态置为下线。

5)publish

当节点收到publish命令,会执行该命令,并向集群发送publish,其他节点收到后也会执行该命令。

2、消息头

所有消息都由消息头包裹,消息头可以认为是消息的一部分。消息头由cluster.h/clusterMsg结构记录,如下:

         structclusterMsg{
         uint32_t totlen;//消息总长度,包括消息头长度和正文长度
         uint16_t type;//消息类型
         uint16_t count;//消息正文包含节点信息数量,只有在meet、ping、pong这三种涉及到gossip协议的类型使用
         uint64_t currentEpoch;//发送者的配置纪元
uint64_t configEpoch;//该节点是主节点时,是发送者的配置纪元;是从节点时,是对应正在复制的主节点的配置纪元
         char sender[REDIS_CLUSTER_NAMELEN];//发送者名字(ID)
         unsigned char myslots[REDIS_CLUSTER_SLOTS/8];//发送者目前的槽信息
         char slaveof[REDIS_CLUSTER_NAMELEN];//主节点时记录的是40位长的都是0的字符串,从节点时记录的是复制的主节点的名字
         uint16_t port;//发送者端口号
         uint16_t flag;//发送者标识值
         unsigned char state;//发送者所处的集群状态
         union clusterMsgData data;//消息的正文
}clusterMsg;

消息的正文是一个联合体,共有三种类型结构体,包括ping、fail、publish,其中pong、meet类型都和ping一样。

3、meet、ping、pong

这三个的类型一样,都是记录在联合体clusterMsgData中的结构体。因为这三种消息有相同的正文,节点是通过消息头的type判断是这三种的哪一种。

这三种消息的类型是clusterMsgDataPublish,这是一个结构体,记录节点名字、最后给该节点发送ping的时间戳、最后收到节点pong的时间戳、节点ip、端口号、标识等。

当节点接收到信息时,如果不认识里面的节点,则会与节点进行握手,如果认识则更新对应的信息。

4、fail

由于使用gossip协议会有延迟,fail是用来表示该节点下线,需要尽快传达,因此不用gossip协议,而是立即让集群中的全部节点知情。其正文就是下线节点的名字。

5、publish

客户端向集群发送publish<channel> <message>,接收的频道不仅会向频道channel发送message,还会向集群广播publish,其他节点也会执行该命令。

因此,向某个节点发送publish,会导致所有节点都执行该命令。

具体流程如下:

publish用结构体clusterMsgDataPublish记录,内容是包括频道长度,消息长度,以及具体内容。

其中,bulk_data的前channel_len字节,记录channel参数;剩余字节记录message参数。

例如,发送publish“news.it” “hello” 如下:

其实也可以直接向集群广播publish命令,但是由于其不符合redis设计的各节点通过消息发送和接收来传播消息的做法,因此采用对某一节点进行消息发送。

——written by linhxx 2017.09.18

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-09-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java进阶架构师

「mysql优化专题」90%程序员都会忽略的增删改优化(2)

通常情况下,当访问某张表的时候,读取者首先必须获取该表的锁,如果有写入操作到达,那么写入者一直等待读取者完成操作(查询开始之后就不能中断,因此允许读取者完成操作...

492
来自专栏后端技术探索

一次非常有意思的sql优化经历

发现没有用到索引,type全是ALL,那么首先想到的就是建立一个索引,建立索引的字段当然是在where条件的字段。

562
来自专栏北京马哥教育

Linux 中断处理浅析

最近在研究异步消息处理, 突然想起linux内核的中断处理, 里面由始至终都贯穿着”重要的事马上做, 不重要的事推后做”的异步处理思想. 于是整理一下~ ? 第...

3908
来自专栏Golang语言社区

几种服务器端IO模型的简单介绍及实现(上)

一些概念: 同步和异步 同步和异步是针对应用程序和内核的交互而言的,同步指的是用户进程触发I/O操作并等待或者轮询的去查看I/O操作是否就绪,而异步是指用户进程...

3327
来自专栏技术博文

线程,进程和并发

进程 进程是什么?进程是正在执行的程序;进程是正在计算机上执行的程序实例;进程是能分配给处理器并由处理器执行的实体。 进程一般会包括指令集和系统资源集,这里的指...

2727
来自专栏Golang语言社区

几种服务器端IO模型的简单介绍及实现(上)

一些概念: 同步和异步 同步和异步是针对应用程序和内核的交互而言的,同步指的是用户进程触发I/O操作并等待或者轮询的去查看I/O操作是否就绪,而异步是指用户进程...

3238
来自专栏云成本管理

云成本管理方法论(三)——云优化管理之判定规则

云优化管理四个管理维度中管理时点在通用管理模型基础上不需要额外补充,所以主要说明其他三个维度(管理对象、判定规则和管理措施)。另外,为了贴近我们熟悉的优化概念,...

46419
来自专栏北京马哥教育

基础拾遗--【转】什么是长连接、短连接?

什么是长连接,什么是短连接? 贴个经典的,看完了就应该没啥问题了 : TCP/IP通信程序设计的丰富多样性 刚接触TCP/IP通信设计的人根据范例可...

2838
来自专栏散尽浮华

mysql主从同步(5)-同步延迟状态考量(seconds_behind_master和pt-heartbea)

一般情况下,我们是通过"show slave status \G;"提供的Seconds_Behind_Master值来衡量mysql主从同步的延迟情况。具体说...

2488
来自专栏程序猿

MySQL优化方案(一)优化SQL脚本与索引

MySQL的优化方案有哪一些? 本文记录MySQL优化方案 ,梗概如下: 优化SQL 优化索引 (一)优化SQL 1、通过MySQL自有的优化语句 优化SQL语...

3807

扫描关注云+社区