Cassandra源码学习:机架感应策略

前端之家收集整理的这篇文章主要介绍了Cassandra源码学习:机架感应策略前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Snitches概述

Cassandra提供了Snitches功能,可以知道集群中的每个节点所属数据中心和机架。所有机架感应策略都实现了相同的接口IEndpointSnitch。先来看看Snitches的类图:


IEndpointSnitch接口中提供了比较实用的方法

[java]@H_301_22@ view plain copy print ?
  1. //通过ip地址获取机架
  2. publicStringgetRack(InetAddressendpoint);
  3. //通过ip地址获取数据中心
  4. publicStringgetDatacenter(InetAddressendpoint);
  5. //按节点距离排序
  6. publicList<InetAddress>getSortedListByProximity(InetAddressaddress,Collection<InetAddress>unsortedAddress);
  7. //比较节点与指定节点远近
  8. publicintcompareEndpoints(InetAddresstarget,InetAddressa1,InetAddressa2);
  9. //开如gossip协议
  10. publicvoidgossiperStarting();
Snitches按实现分为三种:

(1)SimpleSnitch:这种策略不能识别数据中心和机架信息,适合在单数据中心使用;

(2)NetworkTopologySnitch:这种策略提供了网络拓扑结构,以便更高效地消息路由;

(3)DynamicEndpointSnitch:这种策略可以记录节点之间通信时间间隔,记录节点之间通信速度,从而达到动态选择最合适节点的目的。
SimpleSnitch比较简单就不用介绍了,此类只是一个默认实现。下面主要介绍NetworkTopologySnitch和DynamicEndpointSnitch两种策略。


NetworkTopologySnitch

此策略提供了网络拓扑结构,因此可以知道节点之间的远近关系,该抽象类实现了compareEndpoints方法代码如下:
[java]@H_301_22@ view plain copy print ?
  1. publicintcompareEndpoints(InetAddressaddress,InetAddressa2)
  2. {
  3. if(address.equals(a1)&&!address.equals(a2))
  4. return-1;
  5. if(address.equals(a2)&&!address.equals(a1))
  6. return
  7. StringaddressDatacenter=getDatacenter(address);
  8. Stringa1Datacenter=getDatacenter(a1);
  9. Stringa2Datacenter=getDatacenter(a2);
  10. if(addressDatacenter.equals(a1Datacenter)&&!addressDatacenter.equals(a2Datacenter))
  11. if(addressDatacenter.equals(a2Datacenter)&&!addressDatacenter.equals(a1Datacenter))
  12. StringaddressRack=getRack(address);
  13. Stringa1Rack=getRack(a1);
  14. Stringa2Rack=getRack(a2);
  15. if(addressRack.equals(a1Rack)&&!addressRack.equals(a2Rack))
  16. if(addressRack.equals(a2Rack)&&!addressRack.equals(a1Rack))
  17. return0;
  18. }
1、先比较ip地址,如果其中一个节点的ip地址与给定节点相同,另一个不相同,则返回;
2、到这里表示3个节点ip均不相同,与1一样,比较数据中心,然后比较机架;
3、到这里表示同数据中心,同机架,返回0.
这里用到了两个方法:getDatacenter和getRack,不同的子类实现不同。AbstractNetworkTopologySnitch有四个子类实现:

PropertyFileSnitch

使用属性文件配置拓扑结构,该文件位于conf/cassandra-topology.properties中,配置类似
[html]@H_301_22@
    #DataCenterOne
  1. 175.56.12.105=DC1:RAC1
  2. 175.50.13.200=DC1:RAC1
  3. 175.54.35.197=DC1:RAC1
文件记录数据中心和机架的位置,数据中心名称可以随意定义,集群中的所有节点都应该有相同的配置。获取数据中心和机架直接读取配置文件即可:
    publicStringgetDatacenter(InetAddressendpoint)
  1. String[]info=getEndpointInfo(endpoint);
  2. assertinfo!=null:"Nolocationdefinedforendpoint"+endpoint;
  3. returninfo[0];
  4. }
  5. publicStringgetRack(InetAddressendpoint)
  6. 1];
  7. }


GossipingPropertyFileSnitch

通过属性文件(conf/cassandra-rackdc.properties)定义当前节点的数据中心和机架,并使用Gossip协议传播到其他节点,当cassandra-topology.properties文件存在的时候,cassandra-rackdc.properties只是做为一个备用。配置类似:
    dc=DC1
  1. rack=RAC1
该策略便于快速传播一个节点的变化,一般和PropertyFileSnitch配合使用。其获取数据中心的代码如下:
    if(endpoint.equals(FBUtilities.getBroadcastAddress()))
  1. returnmyDC;
  2. EndpointStateepState=Gossiper.instance.getEndpointStateForEndpoint(endpoint);
  3. if(epState==null||epState.getApplicationState(ApplicationState.DC)==null)
  4. if(psnitch==null)
  5. if(savedEndpoints==null)
  6. savedEndpoints=SystemKeyspace.loadDcRackInfo();
  7. if(savedEndpoints.containsKey(endpoint))
  8. returnsavedEndpoints.get(endpoint).get("data_center");
  9. returnDEFAULT_DC;
  10. else
  11. returnpsnitch.getDatacenter(endpoint);
  12. }
  13. returnepState.getApplicationState(ApplicationState.DC).value;
  14. }
1、如果是本机,直接返回本地配置文件中的数据中心;
2、不是本机的情况:如果接收到了Gossip消息,直接返回Gossip消息中的数据中心;否则返回本机conf/cassandra-topology.properties文件中的数据中心;
机架的获取与数据中心获取类似。

RackInferringSnitch

其实现与PropertyFileSnitch类似,根据ip地址确定数据中心和机架,如图所示:

第二个8位决定数据中心,第三个8位决定机架。

Ec2Snitch

主要使用在单区域数据中心,使用私有ip地址的情况。

DynamicEndpointSnitch

该策略通过监控两个节点的通信时间,来决定最佳选择方案,该策略是默认使用的,也是Cassandra推荐的。该策略和失败检测密切相关,Cassandra失败检测原理基于Hayashibara的一篇论文(http://ddg.jaist.ac.jp/pub/HDY+04.pdf).


参考资料:
http://www.datastax.com/documentation/cassandra/2.0/cassandra/architecture/architectureSnitchesAbout_c.html
源码下载地址git://git.apache.org/cassandra.git
原文链接:https://www.f2er.com/nosql/204192.html

猜你在找的NoSQL相关文章