初始集群,一個真實的故事


前言

現在,講述一個真實的故事!
一天小黑在完成項目任務,美滋滋的開始准備和對象約會的時候。突然接到命令,公司談了個大項目,預計一天后,將會有海量的搜索請求訪問小黑寫的接口。小黑慌了啊!該怎么辦?該怎么辦?是刪庫還是跑路?手里目前就運行着一台es實例、但幸好有三台備用的服務器。你自己該如何搞?趕緊拉個QQ群,把之前的朋友資源都用上!鼓搗一圈,發現沒人能救得了自己!這個苦逼群主就管理自己!后來就准備死磕es了。謝天謝地,可愛的elasticsearch集群還真能救得了!

在elasticsearch中,一個節點(node)就是一個elasticsearch實例,而一個集群(cluster)由一個或多個節點組成,它們具有相同的cluster.name,並且協同工作,分享數據和負載。當加入新的節點或者刪除一個節點時,集群就會感知到並平衡數據。
當Elasticsearch用於構建高可用和可擴展的系統時(解決小黑的燃眉之急)。擴展的方式可以是:

  • 購買更好的服務器(縱向擴展(vertical scale or scaling up))
  • 購買更多的服務器(橫向擴展(horizontal scale or scaling out))

Elasticsearch雖然能從更強大的硬件中獲得更好的性能,但是縱向擴展有它的局限性。真正的擴展應該是橫向的,它通過增加節點來均攤負載和增加可靠性。
對於大多數數據庫而言,橫向擴展意味着你的程序將做非常大的改動才能利用這些新添加的設備。對比來說,Elasticsearch天生就是分布式的:它知道如何管理節點來提供高擴展和高可用。這意味着你的程序不需要關心這些。
這正好合了小黑的意,正好有三台備用服務器。只需要這個水平擴展就可以繼續美滋滋的去約會了。集群看起來難,做起來——試試看!

向集群中加入節點

小黑首先在本地環境搭建集群,那么只需要三步就行了:

  • 在本地單獨的目錄中,再復制一份elasticsearch文件
  • 分別啟動bin目錄中的啟動文件
  • 貌似沒有第三步了.....

然后,在瀏覽器地址欄輸入:

http://127.0.0.1:9200/_cluster/health?pretty

返回的結果中:

cluster_name	"elasticsearch"
status	"green"
timed_out	false
number_of_nodes	2
number_of_data_nodes	2
active_primary_shards	0
active_shards	0
relocating_shards	0
initializing_shards	0
unassigned_shards	0
delayed_unassigned_shards	0
number_of_pending_tasks	0
number_of_in_flight_fetch	0
task_max_waiting_in_queue_millis	0
active_shards_percent_as_number	100

通過number_of_nodes可以看到,目前集群中已經有了兩個節點了。小黑一看,這完事了啊!走走走,去約會!

發現節點

小黑在約會的路上突然對一個問題很好奇,這兩個es實例是如何發現相互發現,並且自動的加入集群的?誰是群主?不由自主的思考入迷......
es使用兩種不同的方式來發現對方:

  • 廣播
  • 單播

也可以同時使用兩者,但默認的廣播,單播需要已知節點列表來完成。

廣播

當es實例啟動的時候,它發送了廣播的ping請求到地址224.2.2.4:54328。而其他的es實例使用同樣的集群名稱響應了這個請求。

一般這個默認的集群名稱就是上面的cluster_name對應的elasticsearch。通常而言,廣播是個很好地方式。想象一下,廣播發現就像你大吼一聲:別說話了,再說話我就發紅包了!然后所有聽見的紛紛響應你。
但是,廣播也有不好之處,過程不可控。

單播

當節點的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]"]

大家就像交換微信名片一樣,相互傳傳就加群了.....

一般的,我們沒必要關閉單播發現,如果你需要廣播發現的話,配置文件中的列表保持空白即可。

選取主節點

無論是廣播發現還是到單播發現,一旦集群中的節點發生變化,它們就會協商誰將成為主節點,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,由於網絡和負荷等原因,原集群被分為了兩個switchnode1 、2node3、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次),無果的話,宣布節點失聯,並且在需要的時候進行新的分片和主節點選舉。
根據開發環境,適當修改這些值。
小黑覺得研究的差不多了就美滋滋的要繼續約會,但是恍然大悟——我是條單身狗,哪來的女朋友,就看着右手,陷入了沉思........


歡迎斧正,that's all see also:[elasticsearch的master選舉機制](https://www.cnblogs.com/zziawanblog/p/6577383.html)


免責聲明!

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



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