Elasticsearch之集羣腦裂

 

 

 

集羣腦裂是什麼?html

  所謂腦裂問題(相似於精神分裂),就是同一個集羣中的不一樣節點,對於集羣的狀態有了不同的理解。node

   因爲某些節點的失效,部分節點的網絡鏈接會斷開,並造成一個與原集羣同樣名字的集羣,這種狀況成爲集羣腦裂(split-brain)現象。這個問題很是危險,由於兩個新造成的集羣會同時索引和修改集羣的數據。安全

 

 

 

 

 

 

 

 

 

 

 

 

  今天,Elasticsearch集羣出現了查詢極端緩慢的狀況,經過如下命令查看集羣狀態服務器

  curl -XGET 'http://master:9200/_cluster/health'網絡

    或者curl

  curl -XGET 'http://localhost:9200/_cluster/health'elasticsearch

 

  發現,集羣的整體狀態是red,原本9個節點的集羣,在結果中只顯示了4個;可是,將請求發向不一樣的節點以後,我卻發現即便是整體狀態是red的,可是可用的節點數量卻不一致。ide

  正常狀況下,集羣中的全部的節點,應該對集羣中master的選擇是一致的,這樣得到的狀態信息也應該是一致的,不一致的狀態信息,說明不一樣的節點對master節點的選擇出現了異常——也就是所謂的腦裂問題。這樣的腦裂狀態直接讓節點失去了集羣的正確狀態,致使集羣不能正常工做。ui

 

 

 

 

ES集羣腦裂可能致使的緣由:
  1. 網絡: 因爲是內網通訊, 網絡通訊問題形成某些節點認爲 master 死掉, 而另選 master的可能性較小; 進而檢查 Ganglia 集羣監控, 也沒有發現異常的內網流量, 故此緣由能夠排除。url

   內網通常不會出現es集羣的腦裂問題,能夠監控內網流量狀態。外網的網絡出現問題的可能性大些。

 

  2. 節點負載: 因爲 master 節點與 data 節點都是混合在一塊兒的, 因此當工做節點的負載較大( 確實也較大) 時, 致使對應的 ES 實例中止響應, 而這臺服務器若是正充當着 master節點的身份, 那麼一部分節點就會認爲這個 master 節點失效了, 故從新選舉新的節點, 這時就出現了腦裂; 同時因爲 data 節點上 ES 進程佔用的內存較大, 較大規模的內存回收操做也能形成 ES 進程失去響應。 因此, 這個緣由的可能性應該是最大的。
  

   三、回收內存

  因爲data節點上es進程佔用的內存較大,較大規模的內存回收操做也能形成es進程失去響應。

 

 

 

 

 

 

ES集羣腦裂應對問題的辦法:
  一、對應於上面的分析, 推測出緣由應該是因爲節點負載致使了 master 進程中止響應, 繼而致使了部分節點對於 master 的選擇出現了分歧。 爲此, 一個直觀的解決方案即是將 master節點與 data 節點分離。 爲此, 咱們添加了三臺服務器進入 ES 集羣, 不過它們的角色只是master 節點, 不擔任存儲和搜索的角色, 故它們是相對輕量級的進程。 能夠經過如下配置來限制其角色:

  node.master: true
  node.data: false


  固然, 其它的節點就不能再擔任 master 了, 把上面的配置反過來便可。 這樣就作到了將 master 節點與 data 節點分離。固然,爲了使新加入的節點快速肯定master位置,能夠將data節點的默認的master發現方式有multicast修改成unicast:

  discovery.zen.ping.multicast.enabled: false  

  discovery.zen.ping.unicast.hosts: ["master1", "master2", "master3"]  

 

  還有兩個直觀的參數能夠減緩腦裂問題的出現:
  二、discovery.zen.ping_timeout( 默認值是 3 秒) : 默認狀況下, 一個節點會認爲, 若是 master節點在 3 秒以內沒有應答, 那麼這個節點就是死掉了, 而增長這個值, 會增長節點等待響應的時間, 從必定程度上會減小誤判。

  三、discovery.zen.minimum_master_nodes( 默認是 1) : 這個參數控制的是, 一個節點須要看到的具備 master 節點資格的最小數量, 而後才能在集羣中作操做。 官方的推薦值是(N/2)+1, 其中 N 是具備 master 資格的節點的數量( 咱們的狀況是 3, 所以這個參數設置爲2, 但對於只有 2 個節點的狀況, 設置爲 2 就有些問題了, 一個節點 DOWN 掉後, 你確定連不上 2 臺服務器了, 這點須要注意) 。

  以上的解決方法只能是減緩這種現象的發生, 並無從根本上杜絕。


 

 

若是發生了腦裂, 如何解決?
  當腦裂發生後, 惟一的修復辦法是解決這個問題並重啓集羣。 這兒有點複雜和可怕。 當elasticsearch 集羣啓動時, 會選出一個主節點( 通常是啓動的第一個節點被選爲主) 。 因爲索引的兩份拷貝已經不同了, elasticsearch 會認爲選出來的主保留的分片是「主拷貝」並將這份拷貝推送給集羣中的其餘節點。 這很嚴重。 讓咱們設想下你是用的是 node 客戶端而且一個節點保留了索引中的正確數據。 但若是是另外的一個節點先啓動並被選爲主, 它會將一份過時的索引數據推送給另外一個節點, 覆蓋它, 致使丟失了有效數據。

 

 


總結
  因此怎麼從腦裂中恢復?

   第一個建議是給全部數據從新索引。

  第二, 若是腦裂發生了, 要十分當心的重啓你的集羣。 停掉全部節點並決定哪個節點第一個啓動。 若是須要, 單獨啓動每一個節點並分析它保存的數據。 若是不是有效的, 關掉它, 並刪除它數據目錄的內容( 刪前先作個備份) 。 若是你找到了你想要保存數據的節點, 啓動它而且檢查日誌確保它被選爲主節點。 這以後你能夠安全的啓動你集羣裏的其餘節點了。

 

 

 

 

 

詳細分析es節點的幾種角色

 

              https://www.elastic.co/guide/en/elasticsearch/reference/2.4/modules-node.html#_node_data_path_settings

相關文章
相關標籤/搜索