Cassandra提供了Snitches功能,可以知道集群中的每个节点所属数据中心和机架。所有机架感应策略都实现了相同的接口IEndpointSnitch。先来看看Snitches的类图:
IEndpointSnitch接口中提供了比较实用的方法:
//通过ip地址获取机架 public String getRack(InetAddress endpoint); //通过ip地址获取数据中心 public String getDatacenter(InetAddress endpoint); //按节点距离排序 public List<InetAddress> getSortedListByProximity(InetAddress address, Collection<InetAddress> unsortedAddress); //比较节点与指定节点远近 public int compareEndpoints(InetAddress target, InetAddress a1, InetAddress a2); //开如gossip协议 public void gossiperStarting();Snitches按实现分为三种:
(1)SimpleSnitch:这种策略不能识别数据中心和机架信息,适合在单数据中心使用;
(2)NetworkTopologySnitch:这种策略提供了网络拓扑结构,以便更高效地消息路由;
(3)DynamicEndpointSnitch:这种策略可以记录节点之间通信时间间隔,记录节点之间通信速度,从而达到动态选择最合适节点的目的。
SimpleSnitch比较简单就不用介绍了,此类只是一个默认实现。下面主要介绍NetworkTopologySnitch和DynamicEndpointSnitch两种策略。
public int compareEndpoints(InetAddress address, InetAddress a1, InetAddress a2)
{
if (address.equals(a1) && !address.equals(a2))
return -1;
if (address.equals(a2) && !address.equals(a1))
return 1;
String addressDatacenter = getDatacenter(address);
String a1Datacenter = getDatacenter(a1);
String a2Datacenter = getDatacenter(a2);
if (addressDatacenter.equals(a1Datacenter) && !addressDatacenter.equals(a2Datacenter))
return -1;
if (addressDatacenter.equals(a2Datacenter) && !addressDatacenter.equals(a1Datacenter))
return 1;
String addressRack = getRack(address);
String a1Rack = getRack(a1);
String a2Rack = getRack(a2);
if (addressRack.equals(a1Rack) && !addressRack.equals(a2Rack))
return -1;
if (addressRack.equals(a2Rack) && !addressRack.equals(a1Rack))
return 1;
return 0;
}1、先比较ip地址,如果其中一个节点的ip地址与给定节点相同,另一个不相同,则返回;# Data Center One 175.56.12.105=DC1:RAC1 175.50.13.200=DC1:RAC1 175.54.35.197=DC1:RAC1该文件记录数据中心和机架的位置,数据中心名称可以随意定义,集群中的所有节点都应该有相同的配置。获取数据中心和机架直接读取配置文件即可:
public String getDatacenter(InetAddress endpoint)
{
String[] info = getEndpointInfo(endpoint);
assert info != null : "No location defined for endpoint " + endpoint;
return info[0];
}
public String getRack(InetAddress endpoint)
{
String[] info = getEndpointInfo(endpoint);
assert info != null : "No location defined for endpoint " + endpoint;
return info[1];
}
dc =DC1 rack =RAC1
public String getDatacenter(InetAddress endpoint)
{
if (endpoint.equals(FBUtilities.getBroadcastAddress()))
return myDC;
EndpointState epState = Gossiper.instance.getEndpointStateForEndpoint(endpoint);
if (epState == null || epState.getApplicationState(ApplicationState.DC) == null)
{
if (psnitch == null)
{
if (savedEndpoints == null)
savedEndpoints = SystemKeyspace.loadDcRackInfo();
if (savedEndpoints.containsKey(endpoint))
return savedEndpoints.get(endpoint).get("data_center");
return DEFAULT_DC;
}
else
return psnitch.getDatacenter(endpoint);
}
return epState.getApplicationState(ApplicationState.DC).value;
}1、如果是本机,直接返回本地配置文件中的数据中心;Cassandra学习笔记之机架感应策略,布布扣,bubuko.com
原文:http://blog.csdn.net/aesop_wubo/article/details/20655989