原文連接:https://qbox.io/blog/optimizing-elasticsearch-how-many-shards-per-indexhtml
翻譯(因爲部分翻譯藉助翻譯工具,有不許確的地方還請見諒):node
大多數Elasticsearch用戶在建立索引時的一個關鍵問題是「我應該使用多少個分片?」在本文中,我將介紹在分片分配時的一些權衡以及不一樣設置帶來的性能影響.。若是你想學習如何神祕化和優化你的分片策略請繼續閱讀。安全
這是一個重要的話題, 不少用戶對如何分片都有所疑惑, 有個最好的理由就是. 在生產環境中, 隨着數據集的不斷增加, 不合理的分配策略可能會給系統的擴展帶來嚴重的問題.elasticsearch
同時, 這方面的文檔介紹也很是少. 不少用戶只想要明確的答案-他們須要特定的答案,而不是模糊的數字範圍和任意大的數字的警告。分佈式
固然,我也有一些答案. 不過先要看看它的定義和描述,咱們提出了幾個常見的用例,併爲每一個用例提供了咱們的建議。ide
若是你剛接觸ElasticSearch, 那麼弄清楚它的幾個術語和核心概念是很是必要的.工具
(若是你已經有ES的相關經驗, 能夠跳過這部分)性能
假設ElasticSearch集羣的部署結構以下:學習
在參考此圖時請記住這些定義:大數據
cluster(集羣) - Elasticsearch集羣由一個或多個節點組成,可經過其集羣名稱進行標識。
node(節點) - 單個Elasticsearch實例。在大多數環境中,每一個節點都在單獨的盒子或虛擬機上運行。
index(索引) - 在Elasticsearch中,索引是文檔的集合。
shard(分片) - 由於Elasticsearch是一個分佈式搜索引擎,索引一般會拆分爲分佈在多個節點上的稱爲分片的元素。Elasticsearch自動管理這些分片的排列。它還根據須要從新平衡分片,所以用戶無需擔憂細節。
replica(副本) - 默認狀況下,Elasticsearch爲每一個索引建立五個主分片和一個副本。這意味着每一個索引將包含五個主分片,每一個分片將具備一個副本。
對於分佈式搜索引擎來講, 分片及副本的分配將是高可用及快速搜索響應的設計核心.主分片與副本都能處理查詢請求, 它們的惟一區別在於只有主分片才能處理索引請求.
在上圖示例中, 咱們的ElasticSearch集羣有兩個節點, 並使用了默認的分片配置. ES自動把這5個主分片分配到2個節點上, 而它們分別對應的副本則在徹底不一樣的節點上. 對,就這是分佈式的概念.
請記住, 索引的number_of_shards
參數只對索引有效而不是對整個集羣生效.該參數定義了每一個索引的主分片數(不是羣集中的主分片總數).
副本主要是爲了提升搜索性能,用戶能夠隨時添加或刪除副本。它們爲您提供了額外的容量、更高的吞吐量和更強的故障切換能力。咱們始終建議生產羣集有兩個副本用於故障轉移。
當在ElasticSearch集羣中配置好你的索引後, 你要明白在集羣運行中你沒法調整分片設置. 若是之後你發現須要調整分片數量, 那麼您須要從新索引全部源文檔-reindex(雖然重建索引比較耗時,但能夠在沒有停機的狀況下完成).
主分片配置很是相似於硬盤分區,其中原始磁盤空間的從新分區須要用戶備份,配置新分區以及將數據重寫到新分區
分配分片時主要考慮的你的數據集的增加趨勢.
咱們也常常會看到一些沒必要要的過分分片場景. 從ES社區用戶對這個熱門主題(分片配置)的分享數據來看, 用戶可能認爲過分分配是個絕對安全的策略(這裏講的過分分配是指對特定數據集, 爲每一個索引分配了超出當前數據量(文檔數)所須要的分片數).
Elastic在早期確實鼓吹過這種作法, 而後不少用戶作的更爲極端--例如分配1000個分片. 事實上, Elastic目前對此持有更謹慎的態度.
稍有富餘是好的, 但過分分配分片倒是大錯特錯. 具體定義多少分片很難有定論, 取決於用戶的數據量和使用方式.一百個不多使用的碎片可能沒問題;而兩個使用量很大的碎片可能太多了.
要知道, 你分配的每一個分片都是有額外的成本的:
每一個分片本質上就是一個Lucene索引, 所以會消耗相應的文件句柄, 內存和CPU資源
每一個搜索請求會調度到索引的每一個分片中. 若是分片分散在不一樣的節點卻是問題不太. 但當分片開始競爭相同的硬件資源時, 性能便會逐步降低
ES使用詞頻統計來計算相關性. 固然這些統計也會分配到各個分片上. 若是在大量分片上只維護了不多的數據, 則將致使最終的文檔相關性較差
咱們的客戶一般認爲隨着業務的增加, 他們的數據量也會相應的增長, 因此頗有必要爲此作長期規劃. 不少用戶相信他們將會遇到暴發性增加(儘管大多數甚至都沒有遇到過峯值), 固然也但願避免從新分片並減小可能的停機時間.
若是你真的擔憂數據的快速增加, 咱們建議你多關心這條限制: ElasticSearch推薦的最大JVM堆空間是30~32G, 因此把你的分片最大容量限制爲30GB, 而後再對分片數量作合理估算. 例如, 你認爲你的數據能達到200GB, 咱們推薦你最多分配7到8個分片.
總之, 不要如今就爲你可能在三年後才能達到的10TB數據作過多分配. 若是真到那一天, 你也會很早感知到性能變化的.
儘管本部分並未詳細討論副本分片, 但咱們推薦你保持適度的副本數並隨時可作相應的增長. 若是你正在部署一個新的環境, 也許你能夠參考咱們的基於副本的集羣的設計.這個集羣有三個節點組成, 每一個分片只分配了副本. 不過隨着需求變化, 你能夠輕易的調整副本數量.
對大數據集, 咱們很是鼓勵你爲索引多分配些分片--固然也要在合理範圍內. 上面講到的每一個分片最好不超過30GB的原則依然使用.
不過, 你最好仍是能描述出每一個節點上只放一個索引分片的必要性. 在開始階段, 一個好的方案是根據你的節點數量按照1.5~3倍的原則來建立分片. 例如,若是你有3個節點, 則推薦你建立的分片數最多不超過9(3x3)個.
隨着數據量的增長,若是你經過集羣狀態API發現了問題,或者遭遇了性能退化,則只須要增長額外的節點便可. ES會自動幫你完成分片在不一樣節點上的分佈平衡.
再強調一次, 雖然這裏咱們暫未涉及副本節點的介紹, 但上面的指導原則依然使用: 是否有必要在每一個節點上只分配一個索引的分片. 另外, 若是給每一個分片分配1個副本, 你所需的節點數將加倍. 若是須要爲每一個分片分配2個副本, 則須要3倍的節點數. 更多詳情能夠參考基於副本的集羣.
不知道你是否有基於日期的索引需求, 而且對索引數據的搜索場景很是少. 也許這些索引量將達到成百上千, 但每一個索引的數據量只有1GB甚至更小. 對於這種相似場景, 我建議你只須要爲索引分配1個分片.
若是使用ES的默認配置(5個分片), 而且使用Logstash按天生成索引, 那麼6個月下來, 你擁有的分片數將達到890個. 再多的話, 你的集羣將難以工做--除非你提供了更多(例如15個或更多)的節點.
想一下, 大部分的Logstash用戶並不會頻繁的進行搜索, 甚至每分鐘都不會有一次查詢. 因此這種場景, 推薦更爲經濟使用的設置. 在這種場景下, 搜索性能並非第一要素, 因此並不須要不少副本. 維護單個副本用於數據冗餘已經足夠. 不過數據被不斷載入到內存的比例相應也會變高.
若是你的索引只須要一個分片, 那麼使用Logstash的配置能夠在3節點的集羣中維持運行6個月. 固然你至少須要使用4GB的內存, 不過建議使用8GB, 由於在多數據雲平臺中使用8GB內存會有明顯的網速以及更少的資源共享.
再次聲明, 數據分片也是要有相應資源消耗,而且須要持續投入.
當索引擁有較多分片時, 爲了組裝查詢結果, ES必須單獨查詢每一個分片(固然並行的方式)並對結果進行合併. 因此高性能IO設備(SSDs)和多核處理器無疑對分片性能會有巨大幫助. 儘管如此, 你仍是要多關心數據自己的大小,更新頻率以及將來的狀態. 在分片分配上並無絕對的答案, 只但願你能從本文的討論中受益.