Elasticsearch部分節點不能發現集羣(腦裂)問題處理

什麼是腦裂?

讓咱們看一個有兩個節點的elasticsearch集羣的簡單狀況。集羣維護一個單個索引並有一個分片和一個複製節點。節點1在啓動時被選舉爲主節點並保存主分片(在下面的schema裏標記爲0P),而節點2保存複製分片(0Rnode

如今,若是在兩個節點之間的通信中斷了,會發生什麼?因爲網絡問題或只是由於其中一個節點無響應(例如stop-the-world垃圾回收),這是有可能發生的。git

兩個節點都相信對方已經掛了。節點1不須要作什麼,由於它原本就被選舉爲主節點。可是節點2會自動選舉它本身爲主節點,由於它相信集羣的一部分沒有主節點了。在elasticsearch集羣,是有主節點來決定將分片平均的分佈到節點上的。節點2保存的是複製分片,但它相信主節點不可用了。因此它會自動提高複製節點爲主節點。github

如今咱們的集羣在一個不一致的狀態了。打在節點1上的索引請求會將索引數據分配在主節點,同時打在節點2的請求會將索引數據放在分片上。在這種狀況下,分片的兩份數據分開了,若是不作一個全量的重索引很難對它們進行重排序。在更壞的狀況下,一個對集羣無感知的索引客戶端(例如,使用REST接口的),這個問題很是透明難以發現,不管哪一個節點被命中索引請求仍然在每次都會成功完成。問題只有在搜索數據時纔會被隱約發現:取決於搜索請求命中了哪一個節點,結果都會不一樣。算法

如何避免腦裂問題

elasticsearch的默認配置很好。可是elasticsearch項目組不可能知道你的特定場景裏的全部細節。這就是爲何某些配置參數須要改爲適合你的需求的緣由。這篇博文裏全部提到的參數均可以在你elasticsearch安裝地址的config目錄中的elasticsearch.yml中更改。安全

要預防腦裂問題,咱們須要看的一個參數就是 discovery.zen.minimum_master_nodes。這個參數決定了在選主過程當中須要 有多少個節點通訊。缺省配置是1.一個基本的原則是這裏須要設置成 N/2+1, N是急羣中節點的數量。 例如在一個三節點的集羣中, minimum_master_nodes應該被設爲 3/2 + 1 = 2(四捨五入)。服務器

讓咱們想象下以前的狀況下若是咱們把 discovery.zen.minimum_master_nodes 設置成 2(2/2 + 1)。當兩個節點的通訊失敗了,節點1會失去它的主狀態,同時節點2也不會被選舉爲主。沒有一個節點會接受索引或搜索的請求,讓全部的客戶端立刻發現這個問題。並且沒有一個分片會處於不一致的狀態。網絡

咱們能夠調的另外一個參數是 discovery.zen.ping.timeout。它的默認值是3秒而且它用來決定一個節點在假設集羣中的另外一個節點響應失敗的狀況時等待多久。在一個慢速網絡中將這個值調的大一點是個不錯的主意。這個參數不止適用於高網絡延遲,還能在一個節點超載響應很慢時起做用。elasticsearch

兩節點集羣?

若是你以爲(或直覺上)在一個兩節點的集羣中把minimum_master_nodes參數設成2是錯的,那就對了。在這種狀況下若是一個節點掛了,那整個集羣就都掛了。儘管這杜絕了腦裂的可能性,但這使elasticsearch另外一個好特性 - 用複製分片來構建高可用性 失效了。spa

若是你剛開始使用elasticsearch,建議配置一個3節點集羣。這樣你能夠設置minimum_master_nodes爲2,減小了腦裂的可能性,但仍然保持了高可用的優勢:你能夠承受一個節點失效但集羣仍是正常運行的。code

但若是已經運行了一個兩節點elasticsearch集羣怎麼辦?能夠選擇爲了保持高可用而忍受腦裂的可能性,或者選擇爲了防止腦裂而選擇高可用性。爲了不這種妥協,最好的選擇是給集羣添加一個節點。這聽起來很極端,但並非。對於每個elasticsearch節點你能夠設置 node.data 參數來選擇這個節點是否須要保存數據。缺省值是「true」,意思是默認每一個elasticsearch節點同時也會做爲一個數據節點。

在一個兩節點集羣,你能夠添加一個新節點並把 node.data 參數設置爲「false」。這樣這個節點不會保存任何分片,但它仍然能夠被選爲主(默認行爲)。由於這個節點是一個無數據節點,因此它能夠放在一臺便宜服務器上。如今你就有了一個三節點的集羣,能夠安全的把minimum_master_nodes設置爲2,避免腦裂並且仍然能夠丟失一個節點而且不會丟失數據。

結論

腦裂問題很難被完全解決。在elasticsearch的問題列表裏仍然有關於這個的問題, 描述了在一個極端狀況下正確設置了minimum_master_nodes的參數時仍然產生了腦裂問題。 elasticsearch項目組正在致力於開發一個選主算法的更好的實現,但若是你已經在運行elasticsearch集羣了那麼你須要知道這個潛在的問題。

如何儘快發現這個很重要。一個比較簡單的檢測問題的方式是,作一個對/_nodes下每一個節點終端響應的按期檢查。這個終端返回一個全部集羣節點狀態的短報告。若是有兩個節點報告了不一樣的集羣列表,那麼這是一個產生腦裂情況的明顯標誌。

 

 

服務啓動過程當中,因爲未能發現集羣,本身選舉本身爲master
致使該問題有可能網絡緣由。由於discovery.zen(es 中一個集羣的服務)超時了尚未找到集羣則選舉本身爲master。
修改設置 discovery.zen.ping_timeout: 120s,原來120s 重啓es1發現正常了。 

discovery.zen.minimum_master_nodes: 2
discovery.zen.fd.ping_retries: 6
discovery.zen.fd.ping_interval: 20s
discovery.zen.ping_timeout: 120s
client.transport.ping_timeout: 120s

總結:

es服務啓動後到發現集羣的時間有點長,若是超時時間設得短則發現不了。這個緣由還未知。只是經過修改設置讓他儘量能找到了集羣了。

相關文章
相關標籤/搜索