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

      

**現象描述**

es1,es2,es3三臺es組成一個集羣,集羣狀態正常,
當es1 服務器重啓後,es1不能加到集羣中,本身選舉本身爲master,這就產生了es集羣中所謂的「腦裂」
, 把es1的es服務重啓後,es1則能正常發現集羣並加入。
當重啓es2服務器後,es2不能加到集羣中,本身選舉本身爲master,也產生了es集羣中所謂的「腦裂」,當
重啓es服務後,仍是不能發現集羣。
當重啓es3服務器後,es3能加到集羣中。正常。


**分析**

三臺es服務器es服務,插件的版本均同樣,配置除了節點名不一樣也同樣。
查看es服務的啓動日誌發現:

    [2015-07-22 16:48:24,628][INFO ][cluster.service  ] [Es_node_10_0_31_2] new_master 
    [Es_node_10_0_31_2][fDJA3kUtTHC7eJuS4h78FA][localhost][inet[/10.0.31.2:9300]]{rack=rack2, 
    master=true}, reason: zen-disco-join (elected_as_master)

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

    discovery.zen.ping.multicast.enabled: false
    discovery.zen.ping_timeout: 120s
    discovery.zen.minimum_master_nodes: 2 #至少要發現集羣可作master的候選節點數,
    client.transport.ping_timeout: 60s
    discovery.zen.ping.unicast.hosts: ["10.0.31.2", "10.0.33.2"]


指明集羣中其它可能爲master的節點ip,以防找不到
用該方法後,重啓es2服務器能正常發現集羣,服務正常。


**實驗後三臺es服務的配置均加了

    discovery.zen.ping.multicast.enabled: false
    discovery.zen.ping_timeout: 120s
    discovery.zen.minimum_master_nodes: 2 
    client.transport.ping_timeout: 60s
    discovery.zen.ping.unicast.hosts: ["10.0.31.2", "10.0.33.2"] 


只是ip,及超時時間略有不一樣,es2的超時時間設得最長。
es2的服務雖然正常了,但啓動日誌中會有個異常,以下:
    [2015-07-22 21:43:29,012][WARN ][transport.netty  ] [Es_node_10_0_32_2] exception 
    
    caught on transport layer [[id: 0x5c87285c]], closing connection
    java.net.NoRouteToHostException: No route to host
    at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
    at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)
    at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.connect
    
    (NioClientBoss.java:152)
    at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.processSelectedKeys
    
    (NioClientBoss.java:105)
    at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.process
    
    (NioClientBoss.java:79)
    at org.elasticsearch.common.netty.channel.socket.nio.AbstractNioSelector.run
    
    (AbstractNioSelector.java:318)
    at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.run
    
    (NioClientBoss.java:42)
    at org.elasticsearch.common.netty.util.ThreadRenamingRunnable.run
    
    (ThreadRenamingRunnable.java:108)
    at org.elasticsearch.common.netty.util.internal.DeadLockProofWorker$1.run
    
    (DeadLockProofWorker.java:42)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    [2015-07-22 21:43:55,839][WARN ][discovery    
懷疑跟網絡有關係,雖然不影響服務。



## 如何避免腦裂問題 ##

**避免腦裂現象**

用到的一個參數是:discovery.zen.minimum_master_nodes。這個參數決定了要選舉一個Master須要多少個節點(最少候選節點數)。默認值是1。根據通常經驗這個通常設置成 N/2 + 1,N是集羣中節點的數量,例如一個有3個節點的集羣,minimum_master_nodes 應該被設置成 3/2 + 1 = 2(向下取整)。

用到的另一個參數是:discovery.zen.ping.timeout,等待ping響應的超時時間,默認值是3秒。若是網絡緩慢或擁塞,建議略微調大這個值。這個參數不單單適應更高的網絡延遲,也適用於在一個因爲超負荷而響應緩慢的節點的狀況。

若是您剛開始使用elasticsearch,建議搭建擁有3個節點的集羣,這種方式能夠把discovery.zen.minimum_master_nodes設置成2,這樣就限制了發生腦裂現象的可能,且保持着高度的可用性:若是你設置了副本,在丟失一個節點的狀況下,集羣仍可運行。

**如何肯定腦裂現象**

在您的集羣裏面儘快識別這個問題很是重要。一個比較容易的方法是定時獲取每個節點/_nodes響應,它返回了集羣中全部節點的狀態報告,若是兩個節點返回的集羣狀態不同,就是一個腦裂狀況發生的警示信號。

    curl GET http://10.10.2.111:9200/_nodes
java

相關文章
相關標籤/搜索