Cassandra Gossip协议的二三事儿
摘要:Gossip协议是Cassandra维护各节点状态的一个重要组件,下面我们以Gossip协议三次握手为线索逐步分析Gossip协议源码。
Gossip协议是Cassandra维护各节点状态的一个重要组件,下面我们以Gossip协议三次握手为线索逐步分析Gossip协议源码。
Gossip协议通过判断节点的generation和version 来确认节点状态信息新旧,如果节点重启,则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协议的二三事儿的更多相关文章
- Dynamo涉及的算法和协议——p2p架构,一致性hash容错+gossip协议获取集群状态+向量时钟同步数据
转自:http://www.letiantian.me/2014-06-16-dynamo-algorithm-protocol/ Dynamo是Amazon的一个分布式的键值系统,P2P架构,没有主 ...
- Cassandra1.2文档学习(2)——节点间通信协议之gossip协议
参考文档:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/a ...
- 数据同步gossip协议原理与应用场景介绍
作者:京东物流 冯鸿儒 1 简介 Gossip是一种p2p的分布式协议.它的核心是在去中心化结构下,通过将信息部分传递,达到全集群的状态信息传播,传播的时间收敛在O(Log(N))以内,其中N是节点的 ...
- 【协议】5、gossip 协议
Gossip是一种去中心化.容错并保证最终一致性的协议. Background:分布式环境 Gossip是为了解决分布式遇到的问题而设计的.由于服务和数据分布在不同的机器上,节点之间的每次交互都伴随着 ...
- Raft算法和Gossip协议
简单介绍下集群数据同步,集群监控用到的两种常见算法. Raft算法 raft 集群中的每个节点都可以根据集群运行的情况在三种状态间切换:follower, candidate 与 leader.lea ...
- Hyperledger Fabric -- gossip 协议
Hyperledger gossip 本文记述了Hyperledger Fabric 中 一种网络数据同步协议--gossip,它的主要作用是致力于账本数据的安全传输,保证不同节点之间状态的同步和 ...
- 【Consul】Consul架构-Gossip协议
Consul使用gossip协议管理成员关系.广播消息到整个集群.详情可参考Serf library,Serf使用到的gossip协议可以参阅"SWIM: Scalable Weakly-c ...
- P2P 网络核心技术:Gossip 协议
背景 Gossip protocol 也叫 Epidemic Protocol (流行病协议),实际上它还有很多别名,比如:“流言算法”.“疫情传播算法”等. 这个协议的作用就像其名字表示的意思一样, ...
- 浅谈集群版Redis和Gossip协议
昨天的文章写了关于分布式系统中一致性哈希算法的问题,文末提了一下Redis-Cluster对于一致性哈希算法的实现方案,今天来看一下Redis-Cluster和其中的重要概念Gossip协议. 1.R ...
- Gossip协议
Gossip数据传播协议: Fabric通过将工作负载划分到事务执行(背书和提交)对等节点和事务排序节点,优化了区块链网络性能.安全性和可伸缩性.这种网络操作的解耦需要一个安全.可靠和可伸缩的数据传播 ...
随机推荐
- Required request body is missing缺失请求体
今天在写项目的时候前台传的参数后台一直接收不到,在网上搜了一些东西试了也没效果.后来发现是因为加了@RequestBody 去掉之后再次尝试就可以了.
- math库常用函数+产生随机数总结
math库常用函数+产生随机数总结 1.对x开平方 double sqrt(x)://返回值为double类型,输入的x类型随意,只要是数的类型 2.求常数e的x次方 double exp(x);// ...
- Chiplet解决芯片技术发展瓶颈
这是IC男奋斗史的第38篇原创 本文1776字,预计阅读4分钟. Chiplet封装是什么 介绍Chiplet前,先说下SOC.Chiplet和SOC是两个相互对立的概念,刚好可以用来互为参照. SO ...
- CF1878 A-G 题解
前言 赛时代码可能比较难看. 为什么 Div3 会出 4 道数据结构. A 判定 \(a\) 中是否有 \(k\) 即可. 赛时代码 B 奇怪的构造题. 令 \(a_1=1,a_2=3\),其他项由上 ...
- 全面掌握胶囊网络:从基础理论到PyTorch实战
本文全面深入地探讨了胶囊网络(Capsule Networks)的原理.构建块.数学模型以及在PyTorch中的实现.通过本文,读者不仅能够理解胶囊网络的基础概念和高级数学原理,还能掌握其在实际问题中 ...
- 一个基于Vue模型的表单生成器
哈喽,我是老鱼,一名致力于在技术道路上的终身学习者.实践者.分享者! Vuetify Form Base是一个基于模型的表单生成器,目的是提供一个工具,以便以较少的努力从任何模型数据生成可编辑的表单, ...
- K8S 组合命令
强制删除namespace kubectl get namespace [namespace-name] -o json | tr -d "\n" | sed "s/\& ...
- 谈谈流计算中的『Exactly Once』特性
本文翻译自 streaml.io 网站上的一篇博文:"Exactly once is NOT exactly the same" ,分析了流计算系统中常说的『Exactly Onc ...
- AcWing100 IncDec Sequence
求出\(a\)的差分序列\(b\),其中\(b_1 = a_1, b_2 = a_2 - a_1, ... b_n = a_n - a_{n - 1}\) 根据题意以及公式可以发现,如果我们想让序列所 ...
- PIR传感器选型及其使用介绍
(一)PIR简介 PIR传感器(Passive Infrared Sensor),即被动式红外传感器.它因为功耗低,价格低廉,使用简单从而被大量使用在门铃.猫眼.感应开关.小夜灯.安防等消费类产品上. ...