Elasticsearch高階之-叢集搭建,資料分片
es使用兩種不同的方式來發現對方:
- 廣播
- 單播
也可以同時使用兩者,但預設的廣播,單播需要已知節點列表來完成
一 廣播方式
當es例項啟動的時候,它傳送了廣播的ping請求到地址224.2.2.4:54328
。而其他的es例項使用同樣的叢集名稱響應了這個請求。
一般這個預設的叢集名稱就是上面的cluster_name
對應的elasticsearch
。通常而言,廣播是個很好地方式。想象一下,廣播發現就像你大吼一聲:別說話了,再說話我就發紅包了!然後所有聽見的紛紛響應你。
但是,廣播也有不好之處,過程不可控。
#1 在本地單獨的目錄中,再複製一份elasticsearch檔案
# 2 分別啟動bin目錄中的啟動檔案
# 3 在瀏覽器裡輸入:http://127.0.0.1:9200/_cluster/health?pretty
-通過number_of_nodes可以看到,目前叢集中已經有了兩個節點了
二 單播方式
當節點的ip(想象一下我們的ip地址是不是一直在變)不經常變化的時候,或者es只連線特定的節點。單播發現是個很理想的模式。使用單播時,我們告訴es叢集其他節點的ip及(可選的)埠及埠範圍。我們在elasticsearch.yml
配置檔案中設定:
discovery.zen.ping.unicast.hosts: ["10.0.0.1", "10.0.0.3:9300", "10.0.0.6[9300-9400]"]
大家就像交換微信名片一樣,相互傳傳就加群了.....
一般的,我們沒必要關閉單播發現,如果你需要廣播發現的話,配置檔案中的列表保持空白即可。
#現在,我們為這個叢集增加一些單播配置,開啟各節點內的\config\elasticsearch.yml檔案。每個節點的配置如下(原配置檔案都被註釋了,可以理解為空,我寫好各節點的配置,直接貼上進去,沒有動註釋的,出現問題了好恢復):
#1 elasticsearch1節點,,叢集名稱是my_es1,叢集埠是9300;節點名稱是node1,監聽本地9200埠,可以有許可權成為主節點和讀寫磁碟(不寫就是預設的)。
cluster.name: my_es1
node.name: node1
network.host: 127.0.0.1
http.port: 9200
transport.tcp.port: 9300
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300", "127.0.0.1:9302", "127.0.0.1:9303", "127.0.0.1:9304"]
# 2 elasticsearch2節點,叢集名稱是my_es1,叢集埠是9302;節點名稱是node2,監聽本地9202埠,可以有許可權成為主節點和讀寫磁碟。
cluster.name: my_es1
node.name: node2
network.host: 127.0.0.1
http.port: 9202
transport.tcp.port: 9302
node.master: true
node.data: true
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300", "127.0.0.1:9302", "127.0.0.1:9303", "127.0.0.1:9304"]
# 3 elasticsearch3節點,叢集名稱是my_es1,叢集埠是9303;節點名稱是node3,監聽本地9203埠,可以有許可權成為主節點和讀寫磁碟。
cluster.name: my_es1
node.name: node3
network.host: 127.0.0.1
http.port: 9203
transport.tcp.port: 9303
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300", "127.0.0.1:9302", "127.0.0.1:9303", "127.0.0.1:9304"]
# 4 elasticsearch4節點,叢集名稱是my_es1,叢集埠是9304;節點名稱是node4,監聽本地9204埠,僅能讀寫磁碟而不能被選舉為主節點。
cluster.name: my_es1
node.name: node4
network.host: 127.0.0.1
http.port: 9204
transport.tcp.port: 9304
node.master: false
node.data: true
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300", "127.0.0.1:9302", "127.0.0.1:9303", "127.0.0.1:9304"]
由上例的配置可以看到,各節點有一個共同的名字my_es1,但由於是本地環境,所以各節點的名字不能一致,我們分別啟動它們,它們通過單播列表相互介紹,發現彼此,然後組成一個my_es1叢集。誰是老大則是要看誰先啟動了!
三 選取主節點
無論是廣播發現還是到單播發現,一旦叢集中的節點發生變化,它們就會協商誰將成為主節點,elasticsearch認為所有節點都有資格成為主節點。如果叢集中只有一個節點,那麼該節點首先會等一段時間,如果還是沒有發現其他節點,就會任命自己為主節點。
對於節點數較少的叢集,我們可以設定主節點的最小數量,雖然這麼設定看上去叢集可以擁有多個主節點。實際上這麼設定是告訴叢集有多少個節點有資格成為主節點。怎麼設定呢?修改配置檔案中的:
discovery.zen.minimum_master_nodes: 3
一般的規則是叢集節點數除以2(向下取整)再加一。比如3個節點叢集要設定為2。這麼著是為了防止腦裂(split brain)問題。
四 什麼是腦裂
腦裂這個詞描述的是這樣的一個場景:(通常是在重負荷或網路存在問題時)elasticsearch叢集中一個或者多個節點失去和主節點的通訊,然後各節點就開始選舉新的主節點,繼續處理請求。這個時候,可能有兩個不同的叢集在相互執行著,這就是腦裂一詞的由來,因為單一叢集被分成了兩部分。為了防止這種情況的發生,我們就需要設定叢集節點的總數,規則就是節點總數除以2再加一(半數以上)。這樣,當一個或者多個節點失去通訊,小老弟們就無法選舉出新的主節點來形成新的叢集。因為這些小老弟們無法滿足設定的規則數量。
我們通過下圖來說明如何防止腦裂。比如現在,有這樣一個5個節點的叢集,並且都有資格成為主節點:
為了防止腦裂,我們對該叢集設定引數:
discovery.zen.minimum_master_nodes: 3 # 3=5/2+1
之前原叢集的主節點是node1
,由於網路和負荷等原因,原叢集被分為了兩個switch
:node1 、2
和node3、4、5
。因為minimum_master_nodes
引數是3,所以node3、4、5
可以組成叢集,並且選舉出了主節點node3
。而node1、2
節點因為不滿足minimum_master_nodes
條件而無法選舉,只能一直尋求加入叢集(還記得單播列表嗎?),要麼網路和負荷恢復正常後加入node3、4、5
組成的叢集中,要麼就是一直處於尋找叢集狀態,這樣就防止了叢集的腦裂問題。
除了設定minimum_master_nodes
引數,有時候還需要設定node_master
引數,比如有兩個節點的叢集,如果出現腦裂問題,那麼它們自己都無法選舉,因為都不符合半數以上。這時我們可以指定node_master
,讓其中一個節點有資格成為主節點,另外一個節點只能做儲存用。當然這是特殊情況。
那麼,主節點是如何知道某個節點還活著呢?這就要說到錯誤識別了。
五 錯誤識別
其實錯誤識別,就是當主節點被確定後,建立起內部的ping機制來確保每個節點在叢集中保持活躍和健康,這就是錯誤識別。
主節點ping叢集中的其他節點,而且每個節點也會ping主節點來確認主節點還活著,如果沒有響應,則宣佈該節點失聯。想象一下,老大要時不常的看看(迴圈)小弟們是否還活著,而小老弟們也要時不常的看看老大還在不在,不在了就趕緊再選舉一個出來!
但是,怎麼看?多久沒聯絡算是失聯?這些細節都是可以設定的,不是一拍腦門子,就說某個小老弟掛了!在配置檔案中,可以設定:
discovery.zen.fd.ping_interval: 1
discovery.zen.fd.ping_timeout: 30
discovery_zen.fd.ping_retries: 3
每個節點每隔discovery.zen.fd.ping_interval
的時間(預設1秒)傳送一個ping請求,等待discovery.zen.fd.ping_timeout
的時間(預設30秒),並嘗試最多discovery.zen.fd.ping_retries
次(預設3次),無果的話,宣佈節點失聯,並且在需要的時候進行新的分片和主節點選舉。
根據開發環境,適當修改這些值。