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"]