Elasticsearch之集群腦裂

2021-09-07 09:30:37 字數 2880 閱讀 1109

集群腦裂是什麼?

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

由於某些節點的失效,部分節點的網路連線會斷開,並形成乙個與原集群一樣名字的集群,這種情況成為集群腦裂(split-brain)現象。這個問題非常危險,因為兩個新形成的集群會同時索引和修改集群的資料。

今天,elasticsearch集群出現了查詢極端緩慢的情況,通過以下命令

檢視集群狀態

或者curl -xget 'http://localhost:9200/_cluster/health'

發現,集群的總體狀態是red,本來9個節點的集群,在結果中只顯示了4個;但是,將請求發向不同的節點之後,我卻發現即使是總體狀態是red的,但是可用的節點數量卻不一致。

正常情況下,集群中的所有的節點,應該對集群中master的選擇是一致的,這樣獲得的狀態資訊也應該是一致的,不一致的狀態資訊,說明不同的節點對master節點的選擇出現了異常——也就是所謂的腦裂問題。這樣的腦裂狀態直接讓節點失去了集群的正確狀態,導致集群不能正常工作。

es集群腦裂可能導致的原因:

1. 網路: 由於是內網通訊, 網路通訊問題造成某些節點認為 master 死掉, 而另選 master的可能性較小; 進而檢查 ganglia 集群監控, 也沒有發現異常的內網流量, 故此原因可以排除。

內網一般不會出現es集群的腦裂問題,可以監控內網流量狀態。外網的網路出現問題的可能性大些。

2. 節點負載: 由於 master 節點與 data 節點都是混合在一起的, 所以當工作節點的負載較大( 確實也較大) 時, 導致對應的 es 例項停止響應, 而這台伺服器如果正充當著 master節點的身份, 那麼一部分節點就會認為這個 master 節點失效了, 故重新選舉新的節點, 這時就出現了腦裂; 同時由於 data 節點上 es 程序占用的記憶體較大, 較大規模的記憶體**操作也能造成 es 程序失去響應。 所以, 這個原因的可能性應該是最大的。

3、**記憶體

由於data節點上es程序占用的記憶體較大,較大規模的記憶體**操作也能造成es程序失去響應。

es集群腦裂應對問題的辦法:

1、對應於上面的分析, 推測出原因應該是由於節點負載導致了 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"]  

還有兩個直觀的引數可以減緩腦裂問題的出現:

2、discovery.zen.ping_timeout( 預設值是 3 秒) : 預設情況下, 乙個節點會認為, 如果 master節點在 3 秒之內沒有應答, 那麼這個節點就是死掉了, 而增加這個值, 會增加節點等待響應的時間, 從一定程度上會減少誤判。

3、discovery.zen.minimum_master_nodes( 預設是 1) : 這個引數控制的是, 乙個節點需要看到的具有 master 節點資格的最小數量, 然後才能在集群中做操作。 官方的推薦值是(n/2)+1, 其中 n 是具有 master 資格的節點的數量( 我們的情況是 3, 因此這個引數設定為2, 但對於只有 2 個節點的情況, 設定為 2 就有些問題了, 乙個節點 down 掉後, 你肯定連不上 2 臺伺服器了, 這點需要注意) 。

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

如果發生了腦裂, 如何解決?

當腦裂發生後, 唯一的修復辦法是解決這個問題並重啟集群。 這兒有點複雜和可怕。 當elasticsearch 集群啟動時, 會選出乙個主節點( 一般是啟動的第乙個節點被選為主) 。 由於索引的兩份拷貝已經不一樣了, elasticsearch 會認為選出來的主保留的分片是「主拷貝」並將這份拷貝推送給集群中的其他節點。 這很嚴重。 讓我們設想下你是用的是 node 客戶端並且乙個節點保留了索引中的正確資料。 但如果是另外的乙個節點先啟動並被選為主, 它會將乙份過期的索引資料推送給另乙個節點, 覆蓋它, 導致丟失了有效資料。

總結

所以怎麼從腦裂中恢復?

第乙個建議是給所有資料重新索引。

第二, 如果腦裂發生了, 要十分小心的重啟你的集群。 停掉所有節點並決定哪乙個節點第乙個啟動。 如果需要, 單獨啟動每個節點並分析它儲存的資料。 如果不是有效的, 關掉它, 並刪除它資料目錄的內容( 刪前先做個備份) 。 如果你找到了你想要儲存資料的節點, 啟動它並且檢查日誌確保它被選為主節點。 這之後你可以安全的啟動你集群裡的其他節點了。

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

elasticsearch備份恢復(單機 集群)

參考 版本 7.3 1 伺服器上建立 var backups資料夾,chmod 777 許可權 2 修改elasticsearch.yml檔案,新增 path.repo var backups 3 重啟es 4 建立快照倉庫 5 備份 put6 恢復 post restore7 檢視備份資訊 get...

Elasticsearch實際資料集搜尋操作

載入並建立索引 curl xpost 192.168.110.130 9200 bank account bulk?pretty refresh data binary account.json 1 rest請求uri傳送搜尋引數 curl xget 192.168.110.130 9200 ban...

elasticsearch之mapping中元屬性

1.1 all是乙個特殊的字段,它把其他欄位的值用空格分開,作為乙個大string,進行檢索,預設不會對該字段進行單獨儲存。該欄位通常用於搜尋並不知道該值是否存在文件中,類似迷糊搜尋。例如下面的例子 搜尋包含johe smith 1970任何其中乙個的文件。get my index search 注...