摘要:Gossip协议是Cassandra维护各节点状态的一个重要组件,下面我们以Gossip协议三次握手为线索逐步分析Gossip协议源码。

Gossip协议是Cassandra维护各节点状态的一个重要组件,下面我们以Gossip协议三次握手为线索逐步分析Gossip协议源码。

Gossip协议通过判断节点的generationversion 来确认节点状态信息新旧,如果节点重启,则generation加一,version每次从零开始计算。所以 generation是大版本号,version为小版本号,理解这个概念对后面的握手逻辑有很大帮助。

Gossip协议最重要的一个属性是endpointStateMap ,这个map以address为key,以EndpointState为value维护节点自身状态信息。EndopointState 包含了节点 net_version,host_id,rpc_address,release_version,dc,rack,load,status,tokens 信息。总体来说,所有节点维护的endpointStateMap应该是一致的,如果出现不一致信息或者新增,替换,删除节点 ,这中间的状态维护就要靠Gossip来实现了。

另外一个重要属性subscribers ,当节点状态变更时候,gossip 会通知各个subscribers。

Gossip启动时候,会每隔一秒会在集群中随机选择一个节点发送一条GossipDigestSyn消息,开始和其他节点的通信,如下图:

接下来我们根据上面的了流程图一步步分析gossip代码,GossipDigestSyn 消息是在GossipTask构造的。

1  // syn消息包含 集群名字,分区器,和gDigests消息
2 GossipDigestSyn digestSynMessage = new GossipDigestSyn(DatabaseDescriptor.getClusterName(),DatabaseDescriptor.getPartitionerName(),gDigests);
3
4 MessageOut<GossipDigestSyn> message = new MessageOut<GossipDigestSyn>(MessagingService.Verb.GOSSIP_DIGEST_SYN,digestSynMessage,GossipDigestSyn.serializer);

GossipDigestSyn 消息的主要部分在gDigests里面,gDigests是通过方法Gossiper.instance.makeRandomGossipDigest(gDigests) 生成的。

private  void  makeRandomGossipDigest(List<GossipDigest> gDigests)
02 {
03 EndpointState epState;
04 int generation = 0 ;
05 int maxVersion = 0 ;
06
07 // local epstate will be part of endpointStateMap
08 //当前节点维护的节点列表
09 List<InetAddress> endpoints = new ArrayList<InetAddress>(endpointStateMap.keySet());
10 //乱序处理
11 Collections.shuffle(endpoints, random);
12 for (InetAddress endpoint : endpoints)
13 {
14 epState = endpointStateMap.get(endpoint);
15 if (epState != null )
16 {
17 //获取generation版本号
18 generation = epState.getHeartBeatState().getGeneration();
19 //EndpointState包含了tokens,hostid,status,load等信息,所以冒泡排序获取其中最大的maxVersion
20 maxVersion = getMaxEndpointStateVersion(epState);
21 }
22 gDigests.add( new GossipDigest(endpoint, generation, maxVersion));
23 }
24
25 if (logger.isTraceEnabled())
26 {
27 StringBuilder sb = new StringBuilder();
28 for (GossipDigest gDigest : gDigests)
29 {
30 sb.append(gDigest);
31 sb.append( " " );
32 }
33 logger.trace( "Gossip Digests are : {}" , sb);
34 }
35 }

A节点发出GossipDigestSyn后,B节点会通过GossipDigestSynVerbHandler 来处理GossipDigestSyn 消息,具体处理逻辑在Gossiper.instance.examineGossiper中,

上面方法对比版本号以后,主要处理逻辑在senall方法和requestAll方法,继续跟进:

1  private  void  requestAll(GossipDigest gDigest, List<GossipDigest> deltaGossipDigestList,  int  remoteGeneration)
2 {
3 /* We are here since we have no data for this endpoint locally so request everthing. */
4 //生成一个Digest,等待对方节点发送消息
5 deltaGossipDigestList.add( new GossipDigest(gDigest.getEndpoint(), remoteGeneration, 0 ));
6 if (logger.isTraceEnabled())
7 logger.trace( "requestAll for {}" , gDigest.getEndpoint());
8 }
1 private void sendAll(GossipDigest gDigest, Map<InetAddress, EndpointState> deltaEpStateMap, int maxRemoteVersion)
2 {
3 EndpointState localEpStatePtr = getStateForVersionBiggerThan(gDigest.getEndpoint(), maxRemoteVersion);
4 if (localEpStatePtr != null )
5 //将endpintState信息通过ack 消息发送给对方
6 deltaEpStateMap.put(gDigest.getEndpoint(), localEpStatePtr);
7 }

到这里我们发现向对方节点发送的ack消息已经构造完成了,包含了deltaGossipDigestList(对方节点信息最新,我们需要对方节点给我们发endpointState) 和 deltaEpStateMap(当前节点新,我们发送给对方节点) 。

Gossip 通过GossipDigestAckVerbHandler 处理ack消息,主要逻辑有两块:

1.如果deltaEpStateMap有数据,则说明需要更新本地applicationState,执行Gossiper.instance.applyStateLocally方法

2.如果deltaGossipDigestList 有数据,则说明对方节点需要更新,构造EndpointState,并发送ack2消息给对方

GossipDigestAck2VerbHandler 用来处理 ack2消息,主要逻辑也在Gossiper.instance.applyStateLocally中,我们看一下Gossiper.instance.applyStateLocally的逻辑:

到这里Gossip 三次握手的全过程就分析完了(由于平台字数限制,部分代码以图片形式展示,可点击放大查看哦)。

点击关注,第一时间了解华为云新鲜技术~

Cassandra Gossip协议的二三事儿的更多相关文章

  1. Dynamo涉及的算法和协议——p2p架构,一致性hash容错+gossip协议获取集群状态+向量时钟同步数据

    转自:http://www.letiantian.me/2014-06-16-dynamo-algorithm-protocol/ Dynamo是Amazon的一个分布式的键值系统,P2P架构,没有主 ...

  2. Cassandra1.2文档学习(2)——节点间通信协议之gossip协议

    参考文档:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/a ...

  3. 数据同步gossip协议原理与应用场景介绍

    作者:京东物流 冯鸿儒 1 简介 Gossip是一种p2p的分布式协议.它的核心是在去中心化结构下,通过将信息部分传递,达到全集群的状态信息传播,传播的时间收敛在O(Log(N))以内,其中N是节点的 ...

  4. 【协议】5、gossip 协议

    Gossip是一种去中心化.容错并保证最终一致性的协议. Background:分布式环境 Gossip是为了解决分布式遇到的问题而设计的.由于服务和数据分布在不同的机器上,节点之间的每次交互都伴随着 ...

  5. Raft算法和Gossip协议

    简单介绍下集群数据同步,集群监控用到的两种常见算法. Raft算法 raft 集群中的每个节点都可以根据集群运行的情况在三种状态间切换:follower, candidate 与 leader.lea ...

  6. Hyperledger Fabric -- gossip 协议

    Hyperledger gossip   本文记述了Hyperledger Fabric 中 一种网络数据同步协议--gossip,它的主要作用是致力于账本数据的安全传输,保证不同节点之间状态的同步和 ...

  7. 【Consul】Consul架构-Gossip协议

    Consul使用gossip协议管理成员关系.广播消息到整个集群.详情可参考Serf library,Serf使用到的gossip协议可以参阅"SWIM: Scalable Weakly-c ...

  8. P2P 网络核心技术:Gossip 协议

    背景 Gossip protocol 也叫 Epidemic Protocol (流行病协议),实际上它还有很多别名,比如:“流言算法”.“疫情传播算法”等. 这个协议的作用就像其名字表示的意思一样, ...

  9. 浅谈集群版Redis和Gossip协议

    昨天的文章写了关于分布式系统中一致性哈希算法的问题,文末提了一下Redis-Cluster对于一致性哈希算法的实现方案,今天来看一下Redis-Cluster和其中的重要概念Gossip协议. 1.R ...

  10. Gossip协议

    Gossip数据传播协议: Fabric通过将工作负载划分到事务执行(背书和提交)对等节点和事务排序节点,优化了区块链网络性能.安全性和可伸缩性.这种网络操作的解耦需要一个安全.可靠和可伸缩的数据传播 ...

随机推荐

  1. 【开源】给ChatGLM写个,Java对接的SDK

    作者:小傅哥 - 百度搜 小傅哥bugstack 博客:bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 大家好,我是技术UP主小傅哥. 清华大学计算机系的超大规模训练模型 Cha ...

  2. CF339D

    题目简化与分析: 题目翻译说的还是太复杂了,其实只是给你 $ n $ 个数,奇数位 \(\operatorname{or}\),偶数位 \(\operatorname{xor}\). 会修改某个元素 ...

  3. 手撕Vue-编译指令数据

    经过上一篇的分析,完成了查找指令和模板的功能,接下来就是编译指令的数据了. 所以本章节主要处理的方法则是 buildElement 方法,我们先分析一下我们所拿到的数据在进行编码,这样会更加清晰一些. ...

  4. 从零用VitePress搭建博客教程(3) - VitePress页脚、标题logo、最后更新时间等相关细节配置

    接上一节:从零用VitePress搭建博客教程(2) –VitePress默认首页和头部导航.左侧导航配置 五.默认主题相关细节配置 关于默认主题的标题,logo.页脚,最后更新时间等相关细节配置,我 ...

  5. ansible平台

    1.ansible概念: 1)ansible和saltstck是目前互联网IT运维人员使用最多的自动化运维管理工具,主要用于对批量(并行)Linux服务器:安装.部署.配置.指令操作.任务计划.参数调 ...

  6. 记一个 Android 14 适配引发的Android 存储权限问题

    一.bug 背景 项目中有下面这样一段代码,在 Android T 版本运行正常,现在适配到 Android U 上之后,运行时 crash 了.... ... values.put(MediaSto ...

  7. 记录一次金仓V8R3数据库坏块处理过程、PostgreSQL数据库适用

    因数广政务云华为业务存储固件升级,导致数据库产生坏块,业务SQL查询报错如下: ERROR: missing chunk number 0 for toast value 38166585 in SY ...

  8. 提升运维效率:轻松掌握JumpServer安装和使用技巧

    前言 JumpServer 是一个开源的跳板机的解决方案,提供了对远程服务器的安全访问.会话录制和审计.用户身份管理等功能,适用于需要管理机器资源&大量服务器资源的情况. 本文将在分享 doc ...

  9. JavaWeb项目练习(学生选课管理系统)二【新建数据库】

    思路 1.页面美化css这部分,挖个坑,我打算做好一点所以先空着.× 2.需要做四个数据表(学生.教师.管理员.课程) 关联: 学生有个人课表 教师有教授课程和个人课表 管理员有全部权限(关联所有数据 ...

  10. 记一次逆向分析解密还原Class文件

    前言 前阵子我的一位朋友发来一份代码让我帮忙看看.具体就是所有的jsp文件内容和大小都一样,漏洞挖掘无从下手.经过分析发现所有的Class都使用了自定义的加密工具加密,经过逆向分析,顺利解密,因而有了 ...