ES集群啟動流程


ES集群是主從模式的,其啟動的過程主要包括主Master選舉,集群元數據選舉,索引主分片選取和副本分片選取。其主要過程如下:

1 Master選舉

集群啟動的第一件事就是選取Master節點,選取的時間點為當集群啟動的備選master節點過半時,開始集群的選舉,這一點和zookeeper是類似的。例如集群有7個節點,有5個節點設置了node.master:true 當這5個備選節點中有超過discovery.zen.minimum_master_nodes(避免腦裂該值應該是半數已上)個節點啟動時,就可以開始選舉主節點。當主節點得票超過半數后,當前節點被選擇為主節點。

2 元數據選舉(恢復)

主節點確定之后,主節點會向所有的節點詢問元數據信息,當收到的元數據過半之后,對比元數據的版本號將版本號最大的元數據作為最新的元數據,並將元數據廣播到集群中。這里的過半指的是候選元數據節點。因為只有這兩個節點可以持久化元數據到磁盤。這里涉及到三個參數:

  • gateway.excepted_nodes:預期節點數,當加入集群的節點數大於該值時即可開始恢復元數據。
  • gateway.recovery_after_time:在叨叨預計節點數之前等待的最長時間,如果在該時間段內,集群還未達到預期節點數,則元數據也開始恢復。默認值為5min
  • gateway.recovery_after_nodes:只要加入集群的節點數量達到當前配置數量則開始恢復元數據。

元數據類型

  • MetaData(集群級),主要存儲clusterID,settings,templates;
  • IndexMetaData(索引級),主要存儲numberOfShards,mappings;
  • ShardStateMetaData(分片級),主要存儲version,indexUUID,primary。
    集群在持久化時不會保存哪個分片位於哪個節點上,這些信息是在在集群元數據和索引元數據恢復完成后,發布一個異步的任務來確定去完成構建路由表的過程。

3 選取分片

在元數據選舉完成后,開始數據分片的選擇。ES為了保證數據的高可用,設計了分片及副本分片,作為准備模式。

3.1 選取主分片

對於主分片,應選取集群中的最新分片。在ES5.X之前,Master會詢問其他節點關於分片的信息,這種情況下,Master節點在短時間內會接收到節點數*分片數的信息,然后宣群每個分片最新的信息,這樣在短時間內,傳輸的數據量交到,在ES5.X之后,ES為每個分片設置了一個shardUUID,並在元數據中保存着哪個分片是主分片。因為ES寫的順序是先寫主分片,然后並發寫副本分片,這樣的機制保證了主分片的數據是最新的。因此元數據記錄的最新主分片即為重啟后的主分片。在重新啟動時,主分片所在的節點可能無法正常啟動,這時候會在in-sync列表里選取一個分片作為主分片。

3.2 選取副本分片

主分片分配完成后,分片匯總信息中的其他分片作為副本分片,如果還不夠,則說明有的分片所在的節點已經無法啟動,這時候集群會在其他節點重新分配副本分片。ES並沒有強制要求相同分片的副本不能再同一個節點分配。而kafka則有這樣的要求。

4 分片恢復

在分片分配完成后,則開始了分片數據的恢復。

4.1 主分片恢復

主分片的恢復不會等到副本分片全部選取之后才開始。他是一個獨立的過程。主分片需要恢復的原因是在上此次關機或者集群異常退出時,有些數據可能還沒有刷盤。每次刷盤都會記錄一個syncid,tranlog需要重放syncid后的寫操作。並簡歷Lucene索引。

4.2 副本分片恢復

副本分片恢復是一個較為復雜的流程,這個流程經過了多次的修改,這個修改的過程與Redis的主從復制面臨着同樣的問題,解決思想也比較相似。

4.2.1 初始版本

初始版本分為兩個階段:

  • phase1:副本節點向主節點發送請求復制,這時候主節點會將已刷盤的數據制作快照,並將快照發送到副本節點。同時在translog上加鎖,為了保留在恢復的過程中執行的寫操作。
  • phase2:將translog做快照,快照中包括從phase1開始,到執行translog過程中新增的索引數據,將這些translog回放。

這個版本的恢復存在的問題是,不管副本分片之前有無數據都需要復制主分片的所有數據。當數據量較大時,phase1需要執行很長時間,這回帶來兩個問題:

  • 不必要的數據傳輸,如果副本分片之前存在大部分數據,或者整體的數據,phase1的數據不需要進行。
  • phase1如果執行時間較長,這時候主節點的translog由於被鎖住,長時間不能刷盤,translog無法被清理。

4.2.2 最終版本

基於已上的不足,副本的恢復經過,視圖版本,將translog分成多個文件,進化到最終的基於序列號的最終版本。分片在每次刷盤是都會記錄當前分片刷盤的sequenceNumber。副本在恢復時會將自己的sequenceNumber發送給主分片,如果sequenceNumber在translog中,則直接使用translog恢復,否則才制作phase1中的快照。

4.2.3 值覆蓋問題解決

當副本分片執行完phase1后就可以接收集群的寫入請求了。這時候會存在一個問題,恢復過程中舊值被新值覆蓋的問題。例如文檔ID為docId的值剛開始為4。這個值在translog中,主副本分片都沒有來及刷盤服務器重啟了,當phase1執行完之后,集群接收到請求將docId設置為4,這時候如果副本分片先執行了修改值,然后重放translog。這時候docId的值就會被覆蓋為3。
ES引入了版本號來解決這個問題。版本號由主分片分配,當發現存在舊版本數據覆蓋新版本數據時,會放棄覆蓋來解決這個問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM