Elasticsearch 叢集重要配置的修改
Elasticsearch 已經有了很好的預設值,特別是涉及到效能相關的配置或者選項。 如果你有疑問,最好就不要動它。我們已經目睹了數十個因為錯誤的設定而導致毀滅的叢集, 因為它的管理者總認為改動一個配置或者選項就可以帶來 100 倍的提升。
其它資料庫可能需要調優,但總得來說,Elasticsearch 不需要。 如果你遇到了效能問題,解決方法通常是更好的資料佈局或者更多的節點。 在 Elasticsearch 中很少有“神奇的配置項”, 如果存在,我們也已經幫你優化了!另外,有些邏輯上的配置在生產環境中是應該調整的。 這些調整可能會讓你的工作更加輕鬆,又或者因為沒辦法設定一個預設值(它取決於你的叢集佈局)。
指定名字
Elasticsearch 預設啟動的叢集名字叫elasticsearch
。你最好給你的生產環境的叢集改個名字,改名字的目的很簡單, 就是防止某人的膝上型電腦加入了叢集這種意外。簡單修改成elasticsearch_production
會很省心。
你可以在你的elasticsearch.yml
檔案中修改:
cluster.name: elasticsearch_production
同樣,最好也修改你的節點名字。就像你現在可能發現的那樣, Elasticsearch 會在你的節點啟動的時候隨機給它指定一個名字。你可能會覺得這很有趣,但是當凌晨 3 點鐘的時候, 你還在嘗試回憶哪臺物理機是 Tagak the Leopard Lord 的時候,你就不覺得有趣了。
更重要的是,這些名字是在啟動的時候產生的,每次啟動節點, 它都會得到一個新的名字。這會使日誌變得很混亂,因為所有節點的名稱都是不斷變化的。
這可能會讓你覺得厭煩,我們建議給每個節點設定一個有意義的、清楚的、描述性的名字,同樣你可以在elasticsearch.yml
中配置:
node.name: elasticsearch_005_data
路徑
預設情況下,Elasticsearch 會把外掛、日誌以及你最重要的資料放在安裝目錄下。這會帶來不幸的事故, 如果你重新安裝 Elasticsearch 的時候不小心把安裝目錄覆蓋了。如果你不小心,你就可能把你的全部資料刪掉了。
最好的選擇就是把你的資料目錄配置到安裝目錄以外的地方, 同樣你也可以選擇轉移你的外掛和日誌目錄:
path.data: /path/to/data1,/path/to/data2 # Path to log files: path.logs: /path/to/logs # Path to where plugins are installed: path.plugins: /path/to/plugins
資料可以儲存到多個不同的目錄, 如果將每個目錄分別掛載不同的硬碟,這可是一個簡單且高效實現一個軟磁碟陣列( RAID 0 )的辦法。Elasticsearch 會自動把條帶化(注:RAID 0 又稱為 Stripe(條帶化),在磁碟陣列中,資料是以條帶的方式貫穿在磁碟陣列所有硬碟中的) 資料分隔到不同的目錄,以便提高效能。
多個數據路徑的安全性和效能:
如同任何磁碟陣列( RAID 0 )的配置,只有單一的資料拷貝儲存到硬碟驅動器。如果你失去了一個硬碟驅動器,你肯定會失去該計算機上的一部分資料。 運氣好的話你的副本在叢集的其他地方,可以用來恢復資料和最近的備份。
Elasticsearch 試圖將全部的條帶化分片放到單個驅動器來保證最小程度的資料丟失。這意味著分片 0
將完全被放置在單個驅動器上。 Elasticsearch 沒有一個條帶化的分片跨越在多個驅動器,因為一個驅動器的損失會破壞整個分片。
這對效能產生的影響是:如果您新增多個驅動器來提高一個單獨索引的效能,可能幫助不大,因為 大多數節點只有一個分片和這樣一個積極的驅動器。多個數據路徑只是幫助如果你有許多索引/分片在單個節點上。
多個數據路徑是一個非常方便的功能,但到頭來,Elasticsearch 並不是軟磁碟陣列( software RAID )的軟體。如果你需要更高階的、穩健的、靈活的配置, 我們建議你使用軟磁碟陣列( software RAID )的軟體,而不是多個數據路徑的功能。
最小主節點數
minimum_master_nodes
設定對你的叢集的穩定極其重要。 當你的叢集中有兩個 masters(注:主節點)的時候,這個配置有助於防止腦裂,一種兩個主節點同時存在於一個叢集的現象。
如果你的叢集發生了腦裂,那麼你的叢集就會處在丟失資料的危險中,因為主節點被認為是這個叢集的最高統治者,它決定了什麼時候新的索引可以建立,分片是如何移動的等等。如果你有兩個masters 節點, 你的資料的完整性將得不到保證,因為你有兩個節點認為他們有叢集的控制權。
這個配置就是告訴 Elasticsearch 當沒有足夠 master 候選節點的時候,就不要進行 master 節點選舉,等 master 候選節點足夠了才進行選舉。
此設定應該始終被配置為 master 候選節點的法定個數(大多數個)。法定個數就是( master 候選節點個數 / 2) + 1
。 這裡有幾個例子:
- 如果你有 10 個節點(能儲存資料,同時能成為 master),法定數就是
6
。 - 如果你有 3 個候選 master 節點,和 100 個 data 節點,法定數就是
2
,你只要數數那些可以做 master 的節點數就可以了。 - 如果你有兩個節點,你遇到難題了。法定數當然是
2
,但是這意味著如果有一個節點掛掉,你整個叢集就不可用了。 設定成1
可以保證叢集的功能,但是就無法保證叢集腦裂了,像這樣的情況,你最好至少保證有 3 個節點。
你可以在你的elasticsearch.yml
檔案中這樣配置:
discovery.zen.minimum_master_nodes: 2
minimum_master_nodes
(還有一些其它配置)允許通過 API 呼叫的方式動態進行配置:
PUT /_cluster/settings { "persistent" : { "discovery.zen.minimum_master_nodes" : 2 } }
這將成為一個永久的配置,並且無論你配置項裡配置的如何,這個將優先生效。當你新增和刪除 master 節點的時候,你需要更改這個配置。
叢集恢復方面的配置
當你叢集重啟時,幾個配置項影響你的分片恢復的表現。首先,我們需要明白如果什麼也沒配置將會發生什麼。
想象一下假設你有 10 個節點,每個節點只儲存一個分片,這個分片是一個主分片或者是一個副本分片,或者說有一個有 5 個主分片/1 個副本分片的索引。有時你需要為整個叢集做離線維護(比如,為了安裝一個新的驅動程式), 當你重啟你的叢集,恰巧出現了 5 個節點已經啟動,還有 5 個還沒啟動的場景。
假設其它 5 個節點出問題,或者他們根本沒有收到立即重啟的命令。不管什麼原因,你有 5 個節點在線上,這五個節點會相互通訊,選出一個 master,從而形成一個叢集。 他們注意到資料不再均勻分佈,因為有 5 個節點在叢集中丟失了,所以他們之間會立即啟動分片複製。
最後,你的其它 5 個節點開啟加入了叢集。這些節點會發現它們的資料正在被複制到其他節點,所以他們刪除本地資料(因為這份資料要麼是多餘的,要麼是過時的)。 然後整個叢集重新進行平衡,因為叢集的大小已經從 5 變成了 10。
在整個過程中,你的節點會消耗磁碟和網路頻寬,來回移動資料,因為沒有更好的辦法。對於有 TB 資料的大叢集, 這種無用的資料傳輸需要很長時間。如果等待所有的節點重啟好了,整個叢集再上線,所有的本地的資料都不需要移動。
現在我們知道問題的所在了,我們可以修改一些設定來緩解它。 首先我們要給 ELasticsearch 一個嚴格的限制:
gateway.recover_after_nodes: 8
這將阻止 Elasticsearch 在存在至少 8 個節點(資料節點或者 master 節點)之前進行資料恢復。 這個值的設定取決於個人喜好:整個叢集提供服務之前你希望有多少個節點線上?這種情況下,我們設定為 8,這意味著至少要有 8 個節點,該叢集才可用。
現在我們要告訴 Elasticsearch 叢集中應該有多少個節點,以及我們願意為這些節點等待多長時間:
gateway.expected_nodes: 10
gateway.recover_after_time: 5m
這意味著 Elasticsearch 會採取如下操作:
- 等待叢集至少存在 8 個節點
- 等待 5 分鐘,或者10 個節點上線後,才進行資料恢復,這取決於哪個條件先達到。
這三個設定可以在叢集重啟的時候避免過多的分片交換。這可能會讓資料恢復從數個小時縮短為幾秒鐘。
注意:這些配置只能設定在config/elasticsearch.yml
檔案中或者是在命令列裡(它們不能動態更新)它們只在整個叢集重啟的時候有實質性作用。
最好使用單播代替組播
Elasticsearch 預設被配置為使用單播發現,以防止節點無意中加入叢集。只有在同一臺機器上執行的節點才會自動組成叢集。
雖然組播仍然作為外掛提供, 但它應該永遠不被使用在生產環境了,否則你得到的結果就是一個節點意外的加入到了你的生產環境,僅僅是因為他們收到了一個錯誤的組播訊號。 對於組播本身並沒有錯,組播會導致一些愚蠢的問題,並且導致叢集變的脆弱(比如,一個網路工程師正在搗鼓網路,而沒有告訴你,你會發現所有的節點突然發現不了對方了)。
使用單播,你可以為 Elasticsearch 提供一些它應該去嘗試連線的節點列表。 當一個節點聯絡到單播列表中的成員時,它就會得到整個叢集所有節點的狀態,然後它會聯絡 master 節點,並加入叢集。
這意味著你的單播列表不需要包含你的叢集中的所有節點, 它只是需要足夠的節點,當一個新節點聯絡上其中一個並且說上話就可以了。如果你使用 master 候選節點作為單播列表,你只要列出三個就可以了。 這個配置在elasticsearch.yml
檔案中:
discovery.zen.ping.unicast.hosts: ["host1", "host2:port"]