Elasticsearch究竟要設置多少分片數?

0、引言

本文翻譯自Elasticsearch20170918熱乎的官方博客,原做者:Christian Dahlqvist。 在構建Elasticsearch集羣的初期若是集羣分片設置不合理,可能在項目的中後期就會出現性能問題。緩存

Elasticsearch是一個很是通用的平臺,支持各類各樣的用例,而且爲數據組織和複製策略提供了巨大靈活性。這種靈活性使得做爲ELK新手的你將數據組織成索引和分片變得困難。雖然不必定會在首次啓動時出現問題,但因爲數據量隨時間的推移,可能會致使性能問題。集羣所擁有的數據越多,糾正問題就越困難,甚至有時可能須要從新索引大量數據。安全

當咱們遇到遭遇性能問題的用戶時,能夠追溯到關於數據索引的數據和羣集數量的問題並不罕見。 對於涉及multi-tenancy或使用基於時間的索引的用戶尤爲如此。 在與用戶討論這個問題時(會議、論壇形式),引伸出的一些最多見的問題是:網絡

1)「我應該有多少個分片?」
2)「個人分片應該有多大」?
  • 1
  • 2

這篇博客文章旨在幫助您回答這些問題,併爲使用基於時間的索引的使用案例( 日誌記錄或安全分析 )提供實用的指導。數據結構

一、什麼是分片?

在開始以前,讓咱們約定文章中用到的一些概念和術語。 
Elasticsearch中的數據組織成索引。每個索引由一個或多個分片組成。每一個分片是Luncene索引的一個實例,你能夠把實例理解成自管理的搜索引擎,用於在Elasticsearch集羣中對一部分數據進行索引和處理查詢。併發

【刷新】當數據寫入分片時,它會按期地發佈到磁盤上的新的不可變的Lucene段中,此時它可用於查詢。——這被稱爲刷新。更詳細的解讀請參考: 
http://t.cn/R05e3YRide

【合併】隨着分段數(segment)的增加,這些segment被按期地整合到較大的segments。 這個過程被稱爲合併(merging)。性能

因爲全部段都是不可變的, 由於新的合併段須要建立,舊的分段將被刪除 ,這意味着所使用的磁盤空間一般在索引時會波動。 合併可能資源至關密集,特別是在磁盤I/O方面。測試

分片是Elasticsearch在集羣周圍分發數據的單位。 Elasticsearch在從新平衡數據時 (例如 發生故障後) 移動分片的速度 取決於分片的大小和數量以及網絡和磁盤性能。優化

提示:避免有很是大的分片,由於大的分片可能會對集羣從故障中恢復的能力產生負面影響。 對於多大的分片沒有固定的限制,可是分片大小爲50GB一般被界定爲適用於各類用例的限制。ui

二、索引有效期( retention period )

因爲段是不可變的,更新文檔須要Elasticsearch首先查找現有文檔,而後將其標記爲已刪除,並添加更新的版本。刪除文檔還須要找到文檔並將其標記爲已刪除。所以,刪除的文檔將繼續佔據磁盤空間和一些系統資源,直到它們被合併,這將消耗大量的系統資源。

Elasticsearch容許從文件系統直接刪除完整索引,而沒必要明確地必須單獨刪除全部記錄。這是迄今爲止從Elasticsearch刪除數據的最有效的方式。

提示:儘量使用基於時間的索引來管理數據。根據保留期(retention period,能夠理解成有效期)將數據分組。基於時間的索引還能夠輕鬆地隨時間改變主分片和副本分片的數量(覺得要生成的下一個索引進行更改)。這簡化了適應不斷變化的數據量和需求。

三、索引和分片不是空閒的?

【集羣狀態】對於每一個Elasticsearch索引,其映射和狀態的信息都存儲在集羣狀態。 這些集羣狀態信息保存在內存中以便快速訪問。 所以,若是在集羣中擁有大量索引,可能致使大的集羣狀態(特別是若是映射較大)。 全部更新集羣狀態操做爲了在集羣中保證一致性,須要經過單個線程完成,所以更新速度將變慢。

提示:爲了減小索引數量並避免大的乃至很是龐大的映射,請考慮將相同索引結構的數據存儲在相同的索引中,而不是基於數據的來源將數據分割成獨立的索引。 在每一個索引的索引數量和映射大小之間找到一個很好的平衡很重要。**

每一個分片都有數據須要保存在內存中並使用堆空間。 這包括在分片級別保存信息的數據結構,也包括在段級別的數據結構,以便定義數據駐留在磁盤上的位置。 這些數據結構的大小不是固定的,而且將根據用例而有所不一樣。

然而,段相關開銷的一個重要特徵是它與分段的大小不成正比。 這意味着與較小的段相比,較大的段的每一個數據量具備較少的開銷,且這種差別很大。

【堆內存的重要性】爲了可以每一個節點存儲儘量多的數據,重要的是儘量多地管理堆內存使用量並減小其開銷。 節點擁有的堆空間越多,它能夠處理的數據和分片越多。

所以,索引和分片從集羣的角度看待不是空閒的,由於每一個索引和分片都有必定程度的資源開銷。

提示1:小分片會致使小分段(segment),從而增長開銷。目的是保持平均分片大小在幾GB和幾十GB之間。對於具備基於時間的數據的用例,一般看到大小在20GB和40GB之間的分片。

提示2:因爲每一個分片的開銷取決於分段數和大小,經過強制操做迫使較小的段合併成較大的段能夠減小開銷並提升查詢性能。一旦沒有更多的數據被寫入索引,這應該是理想的。請注意,這是一個消耗資源的(昂貴的)操做,較爲理想的處理時段應該在非高峯時段執行。

提示3:您能夠在集羣節點上保存的分片數量與您可用的堆內存大小成正比,但這在Elasticsearch中沒有的固定限制。 一個很好的經驗法則是:確保每一個節點的分片數量保持在低於每1GB堆內存對應集羣的分片在20-25之間。 所以,具備30GB堆內存的節點最多能夠有600-750個分片,可是進一步低於此限制,您能夠保持更好。 這一般會幫助羣體保持處於健康狀態。

四、分片的大小如何影響性能?

在Elasticsearch中,每一個查詢在每一個分片的單個線程中執行。然而,能夠並行處理多個分片,並能夠在相同分片上執行多個查詢和聚合。

【小分片的利弊】這意味着,在不涉及高速緩存時,最小查詢延遲將取決於數據、查詢的類型、分片的大小。查詢大量小分片將使得每一個分片的處理速度更快,可是隨着更多的任務須要按順序排隊和處理,它不必定要比查詢較小數量的更大的分片更快。若是有多個併發查詢,則有不少小碎片也會下降查詢吞吐量。

提示:從查詢性能角度肯定最大分片大小的最佳方法是使用逼真的數據和查詢進行基準測試(真實數據而非模擬數據)。 始終使用查詢和索引負載進行基準測試,表明節點在生產中須要處理的內容,由於單個查詢的優化可能會產生誤導性的結果。

五、如何管理分片大小?

當使用基於時間的索引時,每一個索引傳統上都與固定的時間段相關聯。 每日索引很是廣泛,常常用於持有時間區間短或每日量大的數據。 這些容許數據期限期間以良好的粒度進行管理,而且能夠方便地對天天更換調整volumes。

時間週期長的數據,特別是若是每日不保存天天的索引數據,則一般會使用每週或每個月的保存的碎片大小的增長。 這減小了隨着時間的流逝須要存儲在羣集中的索引和碎片數量大小(直譯有點費勁此處)。

提示:若是使用固按期限的時間索引數據,能夠根據時間週期和預期數據量調整所涵蓋的時間範圍,以達到目標分片大小。

【均勻更新&快速變化的索引數據對比】具備固定時間間隔的基於時間的索引在數據量合理預測而且變化緩慢的狀況下工做良好。 若是索引率能夠快速變化,則很難保持均勻的目標分片大小。

爲了可以更好地處理這種狀況,推出了Rollover和S**hrink API**。 這些增長了如何管理索引和分片的靈活性,尤爲適用於基於時間的索引。

此處省略了 Rollover和Shrink API的介紹。(建議查詢官網補齊概念再深刻)

六、結論

這篇博客文章提供了有關如何在Elasticsearch中最好地管理數據的提示和實用指南。 若是您有興趣瞭解更多,推薦閱讀Google搜索 「Elasticsearch: the definitive guide」 (有點舊,值得閱讀)。

然而,關於如何最好地在索引和分片上分發數據的許多決策將取決於用例細節,有時可能難以肯定如何最佳地應用可用的建議。

文章說起的幾個核心建議清單以下,以回答文章開頭的提問。

1) 「我應該有多少個分片?」
答: 每一個節點的分片數量保持在低於每1GB堆內存對應集羣的分片在20-25之間。
2) 「個人分片應該有多大」?
答:分片大小爲50GB一般被界定爲適用於各類用例的限制。
  • 1
  • 2
  • 3
  • 4

仍是讀起來有點拗口,一些概念仍是不夠深刻,不能很好的深刻淺出的講解。 待我實踐中更新吧。更多細節,歡迎討論!

相關文章
相關標籤/搜索