ElasticSearch源碼-Discovery模塊

  1. 版本: ElasticSearch 5.4.4
  2. Lucene版本: 6.5.1
  3. java: open jdk 1.8

DIscovery模塊的功能

Discover模塊主要是負責發現集羣中的節點,以及選擇主節點。兼容多種Discovery類型,包含亞馬遜的ec2,谷歌的GCE等 本文內置的爲zenDiscovery。
位置:

Interface:org.elasticsearch.discovery #這時接口類
Discription:
A pluggable module allowing to implement discovery of other nodes, publishing of the cluster
state to all nodes, electing a master of the cluster that raises cluster state change  events.
class: org.elasticsearch.discovery.zen #實現類
主要是爲了進行主節點選取:封裝了節點發現、選主等流程
class: org.elasticsearch.discovery.zen.ElectMasterService 具體的選主實現

主從模式的ES

考慮到ES的實際應用情況:

  • 中等集羣,通常剛沒有那麼多節點(上千個)。
  • 單節點維護的連接數通常少於節點數量
  • 網絡環境比較問題,節點加入和離開不是很頻繁。
    因此考慮上千甚至是數錢節點的加入是沒必要的,因爲沒有采用分佈式哈希表(DHT)而採用的是主從模式。

ES的選主算法

ES主要採用的Bully算法,本質上就是選取id最大或者最小的作爲主節點。當然爲了維持一致性我們還有考慮很多額外的細節問題。這裏首先我們研究一下ElectMasterService類
成員變量

private volatile int minimumMasterNodes;
// 觸發選主所需要的最小節點數量。 必須爲半數以上

成員類

public static class MasterCandidate {
        public static final long UNRECOVERED_CLUSTER_VERSION = -1;
        final DiscoveryNode node;
        final long clusterStateVersion;
        /*此處省略*/
        /**
         * compares two candidates to indicate which the a better master.
         * A higher cluster state version is better
         *
         * @return -1 if c1 is a batter candidate, 1 if c2.
         */
        public static int compare(MasterCandidate c1, MasterCandidate c2) {
            // we explicitly swap c1 and c2 here. the code expects "better" is lower in a sorted
            // list, so if c2 has a higher cluster state version, it needs to come first.
            int ret = Long.compare(c2.clusterStateVersion, c1.clusterStateVersion);
            if (ret == 0) {
                ret = compareNodes(c1.getNode(), c2.getNode());
            }
            return ret;
        }
    }

這裏比較兩個候選節點主要是根據每個節點的clusterStateVersion , clusterStateVersion越大,優先級越高。clusterStateVersion相同時,進入compareNodes,其內部按照節點的Id比較(Id爲節點第一次啓動時隨機生成)取比較小的。當clusterStateVersion越大,優先級越高。這是爲了保證新Master擁有最新的clusterState(即集羣的meta),避免已經commit的meta變更丟失。因爲Master當選後,就會以這個版本的clusterState爲基礎進行更新。

整個流程如下;

  1. 觸發選主: 參與選主流程的必須要有一半以上。
  2. 決定master: 選出臨時master後, 加入其中的節點必須達到法定人數。
  3. gateway選舉元信息:向有master選舉資格的節點發送請求獲取元數據,反饋必須達到法定數量。
  4. master發佈成功數量爲多數。

選取臨時節點:findMaster

org.elasticsearch.discovery.zen.ZenDiscover.findMaster

首先節點會通過ping所有的節點然後獲取節點的列表fullPingResponse,當然肯定不會包括本節點,但是會單獨添加到本節點到fullPingResponse

List<ZenPing.PingResponse> fullPingResponses = pingAndWait(pingTimeout).toList();

然後es會構建兩個列表;activeMasters和masterCandidates

activeMaster: 將每個節點認爲的當前master添加到列表中(除去本身)。正常情況下有一個節點,但是異常情況下也可能存在多個。

masteCandinates: 列表master候選者的列表,遍歷列表確定不具備master資格的節點。

這時如果activeMaster爲空則從masterCandinate選取新的節點 (詳情見electMaterService類實現)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章