1、叢集配置
Elasticsearch 是一個分布式搜尋引擎,可實作快速的資料索引化并具備良好的搜尋性能。
開箱即用的 Elasticsearch 配置可以滿足N多業務場景。但是,如果你想獲得最佳性能,那麼了解索引以及搜尋要求并確定叢集配置符合Elasticsearch最佳實踐至關重要。
Elasticsearch是按業務規模建構的,具有最佳配置可確定更好的叢集性能。Elasticsearch 叢集可拆解為各種可度量的元素,可以将節點視為運作 Elasticsearch 程序的機器。索引本身可以被視為一個完整的搜尋引擎,由一個或多個分片組成。可以将一個分片可視化為 Apache Lucene 的單個執行個體,該執行個體儲存用于索引和搜尋的文檔,并且這些文檔在各個分片之間均勻分布。
圖為:一個三節點叢集,其索引分為六個分片
分片可以提高攝取(ingest)和搜尋性能,但是分片過多也會降低速度。适當的分片政策對于叢集至關重要。建議單個分片大小設定在 30-50 GB 之間。
分片數高于節點數可便于擴充叢集。但是分片的過度配置設定可能會減慢搜尋操作,是因為搜尋首先在 query 階段請求需要命中索引中的每個分片,然後執行 fetch 階段擷取并彙聚結果。
如果你的分片僅容納了 5 GB資料,則可以認為未充分利用。
咱們之前 N 多文章都提過,一個簡單的檢視叢集整體健康狀态的 API 如下:
GET _cluster/health
傳回結果如下:
{
"cluster_name" : "my-application",
"status" : "yellow",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 11,
"active_shards" : 11,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 5,
"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" : 68.75
}
開發人員經常問到的一個問題是:“叢集應該配置的最佳分片數是多少?以使得整個叢集性能最優。”我要說的是,這個問題沒有一個千篇一律的答案。這取決于你的業務要求和你要滿足的SLA(網站服務可用性的保證)。
如下多項統計資訊将幫助你做出正确的容量規劃決策,包含但不限于:
需要每秒索引的文檔數
單文檔大小
每秒查詢數
資料集的增長模式
使用少量資料進行基準性能測試可以幫助你做出正确的決定(劃重點)。
強烈建議你了解您的資料和索引、搜尋要求,以建立一個平衡且高效的叢集。
2、總可用存儲空間大小
如果你的 Elasticsearch 叢集節點的磁盤空間不足,則會影響叢集性能。
一旦可用存儲空間低于特定門檻值限制,它将開始阻止寫入操作,進而影響資料進入叢集。
不少同學可能會遇到過如下的錯誤:
ElasticsearchStatusException[Elasticsearch exception [type=cluster_block_exception, reason=blocked by: [FORBIDDEN/12/index read-only / allow
這就是磁盤快滿了做的保護機制提示。
再次強調一下,磁盤的三個預設警戒水位線。
低警戒水位線
cluster.routing.allocation.disk.watermark.low
預設為磁盤容量的85%。Elasticsearch不會将新的分片配置設定給磁盤使用率超過85%的節點。它也可以設定為絕對位元組值(如500mb),以防止 Elasticsearch 在小于指定的可用空間量時配置設定分片。此設定不會影響新建立的索引的主分片,特别是之前從未配置設定過的分片。
高警戒水位線
cluster.routing.allocation.disk.watermark.high
預設為磁盤容量的90%。Elasticsearch 将嘗試對磁盤使用率超過90%的節點重新配置設定分片(将目前節點的資料轉移到其他節點)。它也可以設定為絕對位元組值,以便在節點小于指定的可用空間量時将其從節點重新配置設定。此設定會影響所有分片的配置設定,無論先前是否配置設定。
洪水警戒水位線
cluster.routing.allocation.disk.watermark.flood_stage
預設為磁盤容量的95%。Elasticsearch對每個索引強制執行隻讀索引塊(index.blocks.read_only_allow_delete)。這是防止節點耗盡磁盤空間的最後手段。隻讀模式待磁盤空間充裕後,需要人工解除。
是以,監視叢集中的可用存儲空間至關重要。
3、已删除的文檔
Elasticsearch中的文檔無法修改,并且是不可變的(immutable)。Elasticsearch 執行的删除或更新文檔操作會先将文檔标記為已删除(邏輯删除),不會立即将其從Elasticsearch中實體删除。當你繼續索引更多資料時,這些文檔将在背景被清理。已邏輯删除的文檔在搜尋操作期間不可見,但是它們繼續占用磁盤空間。
如果磁盤空間成為瓶頸,則可以強制執行段合并操作。段合并會實作小段合并為大段并清理已删除的文檔。
POST my_index/_forcemerge
如果通過 reindex 将文檔重新索引為新索引,則可以執行删除舊索引操作(delete index),删除索引的方式會直接實體删除掉文檔。
如果你的索引會定期更新,則待删除的文檔數量會很多。
是以,最好在磁盤空間出現瓶頸問題前制定适當的政策來清理已邏輯删除的文檔。
4、主節點名額
在生産環境中,建議你在Elasticsearch叢集中配置專用的主節點。
主節點通過監視叢集管理活動(例如:跟蹤叢集中的所有節點、索引和分片)來提高叢集的穩定性。
主節點還監視叢集的運作狀況,以確定資料節點不會過載,并使叢集具有容錯能力。
另一個建議是:針對叢集規模大的場景,建議至少有三個主節點。這樣可確定在發生故障事件期間,必要的仲裁已到位,可以在叢集中選擇新的主節點。
你可以通過檢視主節點的CPU / 記憶體使用率和 JVM 記憶體使用百分比來确定主節點執行個體的配置。
以下是:cerebro 監控 截圖。
一般來說,由于主節點專注于叢集狀态,是以通常需要具有較低CPU /記憶體資源的計算機。
5、資料節點名額
資料節點托管 Elasticsearch 叢集中包含索引文檔的分片。資料節點還執行搜尋和聚合有關的所有資料操作,并處理用戶端請求。
與主節點相比,資料節點需要具有較高CPU / 記憶體資源的伺服器。
如果你的叢集沒有專用的主節點,則其中一個資料節點将開始充當主節點。這會在叢集中造成CPU和JVM使用的不平衡。
文檔增、删、改、查操作和搜尋操作占用大量CPU和IO,是以監視資料節點使用率名額很重要。
從CPU /記憶體的角度來看,您應確定資料節點平衡且不會過載。
6、資料寫入性能名額
如果您試圖将大量文檔寫入 Elasticsearch 中,則可以監視資料寫入延遲和資料索引化速率名額,以驗證索引吞吐量是否滿足企業的需求。
有幾種方法可以提高資料寫入速度。可概括為如下四項措施:
6.1 bulk 批量操作或者多線程寫入
利用 Elasticsearch 提供的批量API(bulk)來同時索引一批文檔。還可以使用多線程寫入 Elasticsearch 以最大化利用所有叢集資源。
請注意,文檔大小和叢集配置可能會影響資料寫入速度。為了找到叢集的最佳吞吐量,你需要運作性能測試并嘗試使用不同的批處理大小和并發線程值大小。
6.2 合理調整重新整理頻率
Elasticsearch refresh 重新整理操作是使文檔可搜尋的過程。
預設情況下,每秒重新整理一次。如果主要目标是調整攝取速度的索引,則可以将 Elasticsearch 的預設重新整理間隔從1秒更改為30秒。30秒後,這将使文檔可見以供搜尋,進而優化索引速度。
更新指定索引的重新整理頻率,實作如下:
PUT my_index/_settings
"index": {
"refresh_interval": "30s"
}
在寫入繁重的業務場景或索引速度比搜尋性能更關鍵的業務場景下,這可能是一個很好的實踐。
6.3 寫入前後動态調整副本大小
副本能提升叢集的高可用并且作為主分片資料的備份能一定程度防止資料丢失,但帶來了相應的成本。
在初始資料加載期間,你可以禁用副本以實作較高的索引寫入速度。
"number_of_replicas": 0
為保證叢集高可用,一旦完成初始加載,就可以重新啟用副本。
6.4 合理的資料模組化
不要索引業務層面不需搜尋的字段。可通過不索引備援字段來節省存儲空間(舉例:設定 index:false)。
如下示例,可以将 cont 字段的 index 屬性值設定為 false,這樣,cont 字段将不會被搜尋。
PUT blog_index
"mappings": {
"properties": {
"cont": {
"type": "text",
"index": false
}
}
如果執意要檢索 cont 字段上的資料,會報錯并傳回如下内容:
"reason": "Cannot search on field [cont] since it is not indexed."
一圖勝千言,模組化的時候仔細過一遍如下這張圖。
是以,強烈建議你根據實際業務場景,以最小化存儲、最大化叢集寫入和搜尋性能為前提對資料進行合理的模組化、合理的設定 Mapping 中的各個字段的類型。
推薦:
論Elasticsearch資料模組化的重要性
Elasticsearch 内部資料結構深度解讀
7、資料搜尋性能名額
Elasticsearch 中的搜尋請求将發送到索引中的所有分片(主分片或副本分片)。然後,接收到該請求的節點将彙集所有分片的結果,并将結果傳回給調用的應用程式。
分片會消耗 CPU / 記憶體資源。是以,如果分片過多,則可能降低查詢性能。
如果叢集的更新操作頻繁,則可能會影響搜尋 SLA。通過适當地配置和水準擴充叢集,可以提升資料寫入和叢集檢索性能。
7.1 使用過濾限定傳回文檔數量
根據我搜尋性能調優的經驗,強烈建議你通過添加适當的過濾器(filters)來限制從搜尋查詢中傳回的文檔數量。應用過濾器後,僅針對有限的一組文檔計算分數,這将提高查詢性能。
你還應該監視搜尋延遲和搜尋速率名額,以調查與搜尋功能相關的性能問題。
這裡說的核心是:不要動不動就傳回全量資料,而是發揮反向索引和搜尋的優勢,根據業務場景最小化傳回滿足給定條件的資料。
7.2 啟用慢查詢日志
建議你在 Elasticsearch 叢集中啟用慢速查詢日志,以解決性能問題并捕獲運作時間較長或超過設定門檻值的查詢。
例如,如果您的搜尋SLA為 2 秒,則可以按以下方式配置搜尋查詢,超過該門檻值的任何查詢都将被記錄。
"index.search.slowlog.threshold.query.warn" : "2s"
8、小結
在本文中,介紹了一些從搜尋和索引角度優化 Elasticsearch 性能的最關鍵的名額。總結一下,關鍵要點如下:
叢集中具有專用的主節點和資料節點,以確定最佳的叢集性能。
通過在叢集中添加資料節點并增加副本分片數量來提升叢集的高可用性。
搜尋查詢必須命中每個分片(主分片或者副本分片),是以分片過多會使搜尋變慢。
慢查詢和索引日志可用來解決搜尋和索引性能問題。
確定你的Elasticsearch叢集在分片、資料節點和主節點的數量上合理性和正确性。
通過利用批量請求、使用多線程寫入并水準擴充叢集來優化 Elasticsearch 索引性能。
注:這是一篇翻譯文章,原文位址:
https://iamondemand.com/blog/top-5-elasticsearch-metrics-to-monitor/我結合業務實踐進行了擴充和完善。
推薦閱讀
Elasticsearch 段合并,這一篇說透了
Elasticsearch叢集規模和容量規劃的底層邏輯
Elasticsearch進階調優方法論之——根治慢查詢!
Elasticsearch性能優化實戰指南
讓Elasticsearch飛起來!——性能優化實踐幹貨