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


免責聲明!

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



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