Cassandra學習筆記之機架感應策略
阿新 • • 發佈:2019-02-09
Snitches概述
Cassandra提供了Snitches功能,可以知道叢集中的每個節點所屬資料中心和機架。所有機架感應策略都實現了相同的介面IEndpointSnitch。先來看看Snitches的類圖:
IEndpointSnitch介面中提供了比較實用的方法:
Snitches按實現分為三種://通過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();
(1)SimpleSnitch:這種策略不能識別資料中心和機架資訊,適合在單資料中心使用;
(2)NetworkTopologySnitch:這種策略提供了網路拓撲結構,以便更高效地訊息路由;
(3)DynamicEndpointSnitch:這種策略可以記錄節點之間通訊時間間隔,記錄節點之間通訊速度,從而達到動態選擇最合適節點的目的。
SimpleSnitch比較簡單就不用介紹了,此類只是一個預設實現。下面主要介紹NetworkTopologySnitch和DynamicEndpointSnitch兩種策略。
NetworkTopologySnitch
此策略提供了網路拓撲結構,因此可以知道節點之間的遠近關係,該抽象類實現了compareEndpoints方法,程式碼如下:1、先比較ip地址,如果其中一個節點的ip地址與給定節點相同,另一個不相同,則返回; 2、到這裡表示3個節點ip均不相同,與1一樣,比較資料中心,然後比較機架; 3、到這裡表示同資料中心,同機架,返回0. 這裡用到了兩個方法:getDatacenter和getRack,不同的子類實現不同。AbstractNetworkTopologySnitch有四個子類實現: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; }
PropertyFileSnitch
使用屬性檔案配置拓撲結構,該檔案位於conf/cassandra-topology.properties中,配置類似該檔案記錄資料中心和機架的位置,資料中心名稱可以隨意定義,叢集中的所有節點都應該有相同的配置。獲取資料中心和機架直接讀取配置檔案即可:# 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];
}
GossipingPropertyFileSnitch
通過屬性檔案(conf/cassandra-rackdc.properties)定義當前節點的資料中心和機架,並使用Gossip協議傳播到其他節點,當cassandra-topology.properties檔案存在的時候,cassandra-rackdc.properties只是做為一個備用。配置類似:dc =DC1
rack =RAC1
該策略便於快速傳播一個節點的變化,一般和PropertyFileSnitch配合使用。其獲取資料中心的程式碼如下:
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、如果是本機,直接返回本地配置檔案中的資料中心;
2、不是本機的情況:如果接收到了Gossip訊息,直接返回Gossip訊息中的資料中心;否則返回本機conf/cassandra-topology.properties檔案中的資料中心;
機架的獲取與資料中心獲取類似。
RackInferringSnitch
其實現與PropertyFileSnitch類似,根據ip地址確定資料中心和機架,如圖所示:第二個8位決定資料中心,第三個8位決定機架。