iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Redis集群节点通信过程/原理流程分析
  • 475
分享到

Redis集群节点通信过程/原理流程分析

2024-04-02 19:04:59 475人浏览 泡泡鱼
摘要

目录简介通信流程Gossip消息消息流程消息格式节点选择1.选择发送消息的节点数量2.消息数据量其他网址简介         本文介绍Redi

简介

        本文介绍Redis的Cluster(集群)的节点通信的流程。

通信流程

        在分布式存储中需要提供维护节点元数据信息的机制, 所谓元数据是指: 节点负责哪些数据, 是否出现故障等状态信息。 常见的元数据维护方式分为: 集中式和P2P方式。 Redis集群采用P2P的Gossip(流言) 协议,Gossip协议工作原理就是节点彼此不断通信交换信息, 一段时间后所有的节点都会知道集群完整的信息, 这种方式类似流言传播, 如下所示

通信过程说明:

  • 集群中的每个节点都会单独开辟一个tcp通道, 用于节点之间彼此通信, 通信端口号在基础端口上加10000。
  • 每个节点在固定周期内通过特定规则选择几个节点发送ping消息。接收到ping消息的节点用pong消息作为响应。
  • 集群中每个节点通过一定规则挑选要通信的节点, 每个节点可能知道全部节点, 也可能仅知道部分节点, 只要这些节点彼此可以正常通信, 最终它们会达到一致的状态。 当节点出故障、 新节点加入、 主从角色变化、 槽信息变更等事件发生时, 通过不断的ping/pong消息通信, 经过一段时间后所有的节点都会知道整个集群全部节点的最新状态, 从而达到集群状态同步的目的。 

Gossip消息

消息流程

        Gossip协议的主要职责就是信息交换。 信息交换的载体就是节点彼此发送的Gossip消息, 了解这些消息有助于我们理解集群如何完成信息交换。

        常用的Gossip消息可分为: ping消息、 pong消息、 meet消息、 fail消息等, 它们的通信模式如下图所示:

  • meet消息: 用于通知新节点加入。

消息发送者通知接收者加入到当前集群, meet消息通信正常完成后, 接收节点会加入到集群中并进行周期性的ping、 pong消息交换。

  • ping消息: 集群内交换最频繁的消息

 集群内每个节点每秒向多个其他节点发送ping消息, 用于检测节点是否在线和交换彼此状态信息。 ping消息发送封装了自身节点和部分其他节点的状态数据。

  • pong消息: 当接收到ping、 meet消息时, 作为响应消息回复给发送方确认消息正常通信。

pong消息内部封装了自身状态数据。 节点也可以向集群内广播自身的pong消息来通知整个集群对自身状态进行更新。
fail消息: 当节点判定集群内另一个节点下线时, 会向集群内广播一个fail消息, 其他节点接收到fail消息之后把对应节点更新为下线状态。 具体细节将在后面“故障转移”中说明。

消息格式

        所有的消息格式划分为: 消息头和消息体。 消息头包含发送节点自身状态数据, 接收节点根据消息头就可以获取到发送节点的相关数据, 结构如下:

typedef struct {
    char sig[4]; 
    uint32_t totlen; 
    uint16_t ver; 
    uint16_t type; 
    uint16_t count; 
    uint64_t currentEpoch; 
    uint64_t configEpoch; 
    uint64_t offset; 
    char sender[CLUSTER_NAMELEN]; 
    unsigned char myslots[CLUSTER_SLOTS/8]; 
    char slaveof[CLUSTER_NAMELEN]; 
    uint16_t port; 
    uint16_t flags; 
    unsigned char state; 
    unsigned char mflags[3]; 
    uNIOn clusterMsgData data ;
} clusterMsg;

        集群内所有的消息都采用相同的消息头结构clusterMsg, 它包含了发送节点关键信息, 如节点id、 槽映射、 节点标识(主从角色, 是否下线) 等。消息体在Redis内部采用clusterMsgData结构声明, 结构如下:

union clusterMsgData {
    
    struct {
        
        clusterMsgDataGossip gossip[1];
    } ping;
    
    
    struct {
        clusterMsgDataFail about;
    } fail;
    // ...
};

        消息体clusterMsgData定义发送消息的数据, 其中ping、 meet、 pong都采用cluster MsgDataGossip数组作为消息体数据, 实际消息类型使用消息头的type属性区分。 每个消息体包含该节点的多个clusterMsgDataGossip结构数据, 用于信息交换, 结构如下:

typedef struct {
    char nodename[CLUSTER_NAMELEN]; 
    uint32_t ping_sent; 
    uint32_t pong_received; 
    char ip[NET_IP_STR_LEN]; 
    uint16_t port; 
    uint16_t flags; 
} clusterMsgDataGossip;

        当接收到ping、 meet消息时, 接收节点会解析消息内容并根据自身的识别情况做出相应处理, 对应流程如下图所示:

接收节点收到ping/meet消息时, 执行解析消息头和消息体流程:

  • 解析消息头过程:

消息头包含了发送节点的信息, 如果发送节点是新节点且消息是meet类型, 则加入到本地节点列表; 如果是已知节点, 则尝试更新发送节点的状态, 如槽映射关系、 主从角色等状态。

  • 解析消息体过程:

如果消息体的clusterMsgDataGossip数组包含的节点是新节点, 则尝试发起与新节点的meet握手流程; 如果是已知节点, 则根据cluster MsgDataGossip中的flags字段判断该节点是否下线, 用于故障转移。
消息处理完后回复pong消息, 内容同样包含消息头和消息体, 发送节点接收到回复的pong消息后, 采用类似的流程解析处理消息并更新与接收节点最后通信时间, 完成一次消息通信。

节点选择

        虽然Gossip协议的信息交换机制具有天然的分布式特性, 但它是有成本的。 由于内部需要频繁地进行节点信息交换, 而ping/pong消息会携带当前节点和部分其他节点的状态数据, 势必会加重带宽和计算的负担。 Redis集群内节点通信采用固定频率(定时任务每秒执行10次) 。 因此节点每次选择需要通信的节点列表变得非常重要。 通信节点选择过多虽然可以做到信息及时交换但成本过高。 节点选择过少会降低集群内所有节点彼此信息交换频率,从而影响故障判定、 新节点发现等需求的速度。 因此Redis集群的Gossip协议需要兼顾信息交换实时性和成本开销, 通信节点选择的规则如下图所示

        根据通信节点选择的流程可以看出消息交换的成本主要体现在单位时间选择发送消息的节点数量和每个消息携带的数据量。

1.选择发送消息的节点数量

        集群内每个节点维护定时任务默认每秒执行10次, 每秒会随机选取5个节点找出最久没有通信的节点发送ping消息, 用于保证Gossip信息交换的随机性。 每100毫秒都会扫描本地节点列表, 如果发现节点最近一次接受pong消息的时间大于cluster_node_timeout/2, 则立刻发送ping消息, 防止该节点信息太长时间未更新。 根据以上规则得出每个节点每秒需要发送ping消息的数
量=1+10*num(node.pong_received>cluster_node_timeout/2) , 因此cluster_node_timeout参数对消息发送的节点数量影响非常大。 当我们的带宽资源紧张时, 可以适当调大这个参数, 如从默认15秒改为30秒来降低带宽占用率。 过度调大cluster_node_timeout会影响消息交换的频率从而影响故障转移、 槽信息更新、 新节点发现的速度。 因此需要根据业务容忍度和资源消耗进行平衡。 同时整个集群消息总交换量也跟节点数成正比。

2.消息数据量

        每个ping消息的数据量体现在消息头和消息体中, 其中消息头主要占用空间的字段是myslots[CLUSTER_SLOTS/8], 占用2KB, 这块空间占用相对固定。 消息体会携带一定数量的其他节点信息用于信息交换。 具体数量见以下伪代码:

def get_wanted():
    int total_size = size(cluster.nodes)
    
    # 默认包含节点总量的1/10
    594int wanted = floor(total_size/10);
    if wanted < 3:
    # 至少携带3个其他节点信息
    wanted = 3;
    if wanted > total_size -2 :
    # 最多包含total_size - 2个
    wanted = total_size - 2;
    return wanted;

        根据伪代码可以看出消息体携带数据量跟集群的节点数息息相关, 更大的集群每次消息通信的成本也就更高, 因此对于Redis集群来说并不是大而全的集群更好, 对于集群规模控制的建议见之后“集群运维”。

其他网址

《Redis开发与运维》=> 第10章 集群=> 10.3 节点通信

到此这篇关于Redis集群节点通信过程/原理的文章就介绍到这了,更多相关Redis集群节点通信内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Redis集群节点通信过程/原理流程分析

本文链接: https://www.lsjlt.com/news/143008.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Redis集群节点通信过程/原理流程分析
    目录简介通信流程Gossip消息消息流程消息格式节点选择1.选择发送消息的节点数量2.消息数据量其他网址简介         本文介绍Redi...
    99+
    2024-04-02
  • Redis集群原理详细分析
    目录一致性哈希Redis 集群一致性哈希 节点的增加和减少,大部分节点的 Hash一致 package consistenthash import ( "hash/crc32" ...
    99+
    2022-12-19
    Redis集群 Redis集群原理 Redis集群模式
  • redis集群原理的示例分析
    这篇文章主要介绍redis集群原理的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!redis集群的原理如果说依靠哨兵可以实现redis的高可用,如果还想在支持高并发同时容纳海...
    99+
    2024-04-02
  • redis集群不通过reids-trib脚本创建3主3从redis集群的示例分析
    这篇文章主要介绍redis集群不通过reids-trib脚本创建3主3从redis集群的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!  1、启动126,127,128 3个7000端口redis(...
    99+
    2023-06-06
  • elasticsearch节点间通信的基础transport启动过程
    目录前言transport启动serverBootStrap如何连接到node连接方法的代码总结前言 在前一篇中我们分析了cluster的一些元素。接下来的章节会对cluster的运...
    99+
    2024-04-02
  • WebSocket中通信过程的示例分析
    小编给大家分享一下WebSocket中通信过程的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!什么是 WebSocket...
    99+
    2024-04-02
  • elasticsearch节点间通信的transport启动过程是什么
    这篇文章主要介绍“elasticsearch节点间通信的transport启动过程是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“elasticsearch节点间通信的transport启动过程...
    99+
    2023-06-30
  • linux下mongodb集群搭建过程的示例分析
    小编给大家分享一下linux下mongodb集群搭建过程的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!mongodb的集群结构如上图网上有个mongo3...
    99+
    2023-06-29
  • Redis线程模型的原理分析
    目录一、概述二、网络IO模型发展史2.1 阻塞IO2.2 非阻塞2.3 IO多路复用三、NIO线程模型解释3.1 单Reactor单线程模型3.2 单Reactor多线程模型3.3 ...
    99+
    2024-04-02
  • SSM框架流程及原理分析
    前言:学ssm框架已经有很长时间,今天来复习一下 SSM图示流程: Spring核心:Java反射 Mybatis:动态代理,而动态代理又是基于反射的,所以,ssm框架核心原理在反...
    99+
    2024-04-02
  • Mybatis通过Spring完成代理类注入的流程分析
    流程分析 首先,使用mybatis的时候会定义mapper接口的基础包,一般我们会用@MapperScanner这个注解,来看下这个注解  来看下这个MapperScan...
    99+
    2024-04-02
  • docker swarm快速部署redis分布式集群的详细过程
    目录环境准备docker搭建Swarm集群打开防火墙(Swarm需要)创建Swarm加入Swarm服务约束单机集群创建容器启动容器进入容器启动集群分布式集群部署docker compose.ymlwait-for-it....
    99+
    2024-04-02
  • docker swarm快速部署redis分布式集群的详细过程
    目录环境准备Docker搭建Swarm集群打开防火墙(Swarm需要)创建Swarm加入Swarm服务约束单机集群创建容器启动容器进入容器启动集群分布式集群部署docker comp...
    99+
    2022-11-13
    docker swarm部署redis redis分布式集群 docker 部署redis
  • redis事件处理流程的案例分析
    这篇文章主要介绍了redis事件处理流程的案例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言:我们知道redis服务器是一个事件驱动...
    99+
    2024-04-02
  • Android Audio音量设置原理流程分析
    Android Audio音量设置原理流程分析 简介 本篇文章主要介绍Android音量设置从App应用层到framework层执行流程,以及相关的细节和原理分析,建议在阅读此文章前去看博主的混音理论篇的声音的音量属性和...
    99+
    2023-08-30
    android
  • Redis命令处理过程实例源码分析
    这篇文章主要介绍“Redis命令处理过程实例源码分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Redis命令处理过程实例源码分析”文章能帮助大家解决问题。本文基于社区版Redis 4.0.81、...
    99+
    2023-06-29
  • Spring Boot应用通过Docker发布部署的流程分析
    目录手动部署1、idea创建spring boot项目2、项目打成 Jar 包3、构建 docker image4、查看并运行镜像插件部署运行推送命令将Spring Boot项目部署...
    99+
    2024-04-02
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理分析
    今天就跟大家聊聊有关SAP CRM里Lead通过工作流自动创建Opportunity的原理分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。(1) 在SAP CRM里创建一个Lead...
    99+
    2023-06-04
  • jsp到servlet后台服务通信过程的示例分析
    这篇文章主要介绍了jsp到servlet后台服务通信过程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。web.xml 文件对于任何一个web 运用来说,有,而且只能...
    99+
    2023-06-02
  • Vue 响应式系统依赖收集过程原理解析
    目录背景目标源码解读入口函数:observeclass ObserverObserve 如何处理数组Observe 如何处理对象class DepDep.targetclass Wa...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作