1. 程式人生 > >ElasticSearch 合理分配索引分片

ElasticSearch 合理分配索引分片

分片定義

假設ElasticSearch叢集的部署結構如下:
這裡寫圖片描述

通過該圖, 記住下面的幾個定義:
叢集(cluster): 由一個或多個節點組成, 並通過叢集名稱與其他叢集進行區分
節點(node): 單個ElasticSearch例項. 通常一個節點執行在一個隔離的容器或虛擬機器中
索引(index): 在ES中, 索引是一組文件的集合
分片(shard): 因為ES是個分散式的搜尋引擎, 所以索引通常都會分解成不同部分, 而這些分佈在不同節點的資料就是分片. ES自動管理和組織分片, 並在必要的時候對分片資料進行再平衡分配, 所以使用者基本上不用擔心分片的處理細節.
副本(replica): ES預設為一個索引建立5個主分片, 並分別為其建立一個副本分片. 也就是說每個索引都由5個主分片成本, 而每個主分片都相應的有一個副本,並且主分片與副本不會在同一個節點上(例如上面的主分片Shard1與副本Replica1就在不同的節點上).

對於分散式搜尋引擎來說, 分片及副本的分配將是高可用及快速搜尋響應的設計核心.主分片與副本都能處理查詢請求, 它們的唯一區別在於只有主分片才能處理索引請求.

在上圖示例中, 我們的ElasticSearch叢集有兩個節點, 並使用了預設的分片配置. ES自動把這5個主分片分配到2個節點上, 而它們分別對應的副本則在完全不同的節點上. 這就是分散式的概念.

請記住, 索引的number_of_shards引數只對當前索引有效而不是對整個叢集生效.對每個索引來講, 該引數定義了當前索引的主分片數(而不是叢集中所有的主分片數).

當在ElasticSearch叢集中配置好你的索引後, 你要明白在叢集執行中你無法調整分片設定. 既便以後你發現需要調整分片數量, 你也只能新建建立並對資料進行重新索引(reindex)(雖然reindex會比較耗時, 但至少能保證你不會停機).

分配分片時主要考慮的你的資料集的增長趨勢

我們也經常會看到一些不必要的過度分片場景. 從ES社群使用者對這個熱門主題(分片配置)的分享資料來看, 使用者可能認為過度分配是個絕對安全的策略(這裡講的過度分配是指對特定資料集, 為每個索引分配了超出當前資料量(文件數)所需要的分片數).

分片都是有額外的成本的:
1. 每個分片本質上就是一個Lucene索引, 因此會消耗相應的檔案控制代碼, 記憶體和CPU資源
2. 每個搜尋請求會排程到索引的每個分片中. 如果分片分散在不同的節點倒是問題不太. 但當分片開始競爭相同的硬體資源時, 效能便會逐步下降
3. ES使用詞頻統計來計算相關性. 當然這些統計也會分配到各個分片上. 如果在大量分片上只維護了很少的資料, 則將導致最終的文件相關性較差

大規模以及日益增長的資料場景

對大資料集, 我們非常鼓勵你為索引多分配些分片–當然也要在合理範圍內. 上面講到的每個分片最好不超過30GB的原則依然使用.

在開始階段, 一個好的方案是根據你的節點數量按照1.5~3倍的原則來建立分片. 例如,如果你有3個節點, 則推薦你建立的分片數最多不超過9(3x3)個.

隨著資料量的增加,如果你通過叢集狀態API發現了問題,或者遭遇了效能退化,則只需要增加額外的節點即可. ES會自動幫你完成分片在不同節點上的分佈平衡.

Logstash的日期索引問題

如果有基於日期的索引需求, 並且對索引資料的搜尋場景非常少. 也許這些索引量將達到成百上千, 但每個索引的資料量只有1GB甚至更小. 對於這種類似場景, 建議你只需要為索引分配1個分片.

如果使用ES的預設配置(5個分片), 並且使用Logstash按天生成索引, 那麼6個月下來, 你擁有的分片數將達到890個. 再多的話, 你的叢集將難以工作–除非你提供了更多(例如15個或更多)的節點.

大部分的Logstash使用者並不會頻繁的進行搜尋, 甚至每分鐘都不會有一次查詢. 所以這種場景, 推薦更為經濟使用的設定. 在這種場景下, 搜尋效能並不是第一要素, 所以並不需要很多副本. 維護單個副本用於資料冗餘已經足夠. 不過資料被不斷載入到記憶體的比例相應也會變高.

如果你的索引只需要一個分片, 那麼使用Logstash的配置可以在3節點的叢集中維持執行6個月. 當然你至少需要使用4GB的記憶體, 不過建議使用8GB, 因為在多資料雲平臺中使用8GB記憶體會有明顯的網速以及更少的資源共享.