1. 程式人生 > >乾貨 | Elasticsearch通用優化建議

乾貨 | Elasticsearch通用優化建議

1、題記

Elasticsearch開發實戰的後期會遇到效能問題,包括:建立索引效能、寫入資料效能、檢索效能等。網上有很多結合自己實際應用場景的相關優化建議,但“對症下藥”才是關鍵。

實際,官網已經有非常明確的相關優化建議。如果沒有實戰場景,一些特性的理解可能不到位。為此,我特定將官網建議做了翻譯,並加了結合實戰開發的通俗理解註釋。

此為第一篇:通用優化一般建議。

後續會跟進索引優化、寫入優化、檢索優化、效能優化篇。

2、認知前提

為更好的理解優化建議,特將文中多次提及的核心概念做了提煉:

2.1 doc values

相比於倒排索引(通過關鍵詞查詢文件),doc values可以直接理解為“正排索引”(通過文件,查詢關鍵詞)。

doc values應用場景:
1)針對某field的排序(sort);
2)針對某field的聚合(aggregation);
3)特定的過濾(舉例:geo 過濾)
4)針對特定欄位的script操作。

2.2 norms

norm是索引的評分因子。 如果您不關心評分,例如,如果您從未按分數對文件進行排序,則可以禁用在索引中儲存這些評分因子並節省一些空間。
禁用方法:

PUT index
{
  "mappings": {
    "type": {
      "properties": {
        "foo": {
          "type": "text"
, "norms": false } } } } }

3、建議1:不要返回大結果資料集

Elasticsearch被設計為搜尋引擎,這使得它非常擅長獲取與查詢匹配的排名靠前的Top文件。 但是,它對於屬於資料庫域的工作負載來說並不好,例如檢索與特定查詢匹配的所有文件。 如果需要檢索全部文件,請確保使用Scroll API。

【銘毅天下註解】:
1)業務開發中,我們有時候需要返回分頁查詢資料,建議使用from+size分頁實現;
2)如果需要返回全量資料,建議使用scroll實現。

4、建議2:避免使用大檔案

鑑於預設的http.max_context_length設定為100MB,Elasticsearch將拒絕索引任何大於該文件的文件。您可能決定增加該特定設定,但Lucene仍然有大約2GB的限制。

即使不考慮硬性指標限制,大型文件通常也不實用。大型文件對網路,記憶體使用和磁碟施加更多壓力,即使對於不請求_source的搜尋請求也是如此,因為Elasticsearch需要在所有情況下獲取文件的_id,並且對於大型文件而言,獲取此欄位的成本更高(歸因於檔案系統快取工作)。

索引大文件將使用數倍於原始文件大小的記憶體,全文搜尋(例如match_phrase短語查詢)和高亮顯示也變得更佔據記憶體呢、更耗時,因為它們的成本直接取決於原始文件的大小。

有時候需要重新考慮資訊單元什麼時候是有用的。例如,您想要對圖書做全文檢索,並不一定意味著一個文件(document)對應一整本書。將章節甚至段落用作document可能是一個更好的主意,然後在這些文件中有一個屬性來標識它們所屬的書。

這不僅避免了大文件的問題,也使搜尋體驗更好。例如,如果使用者搜尋兩個單詞foo和bar,則不同章節之間的匹配可能非常差,而同一段落中的匹配可能很好。

【銘毅天下註解】:
平時的業務場景可能遇不到單文件幾百MB甚至幾GB的場景,但是,在有些知識庫全文檢索的業務中,可能遇到《康熙字典》等類似大文件或其他網路採集大文件資料的檢索。

需要兩點注意:
1)匯入ES前,按照章節或者頁碼進行拆分;
2)設計ES Mapping的時候,採用fvh的高亮模式。

5、建議3:避免稀疏性

Lucene背後的資料結構,也是Elasticsearch依賴的索引和儲存資料,最適合密集資料。舉例:當所有檔案都有相同的欄位時,對於啟用了norms(預設情況下是text文字欄位的情況)或啟用了doc vlaue(預設情況下是數字,日期,IP和關鍵字的情況),尤其如此。

原因是Lucene在內部識別帶有所謂docID的文件,這些docId是介於0和索引中的文件總數之間的整數。這些doc ids用於Lucene的內部API之間的通訊:例如,對某個單元有matchquery的單元上搜索會生成一連串的doc ids,然後這些doc ids用於檢索norm的值以便計算對於這些文件進行評分。

當前實現此norm查詢的方式是為每個文件保留一個位元組。然後,可以通過讀取索引doc_id處的位元組來檢索給定doc id的標準值。雖然這非常有效並且有助於Lucene快速訪問每個文件的標準值,但這樣做的缺點是沒有值的文件也需要一個位元組的儲存空間。

請注意,即使稀疏性最顯著的影響是儲存要求,它也會對索引速度和搜尋速度產生影響,因為沒有欄位的文件的這些位元組仍需要在索引時寫入並在搜尋時花費時間。

在索引中包含少數稀疏欄位是完全沒問題的。 但要注意,如果稀疏性成為規則而不是異常,那麼索引將不會像它那樣有效。

本節主要關注norms 和doc values,因為這些是受稀疏性影響最大的兩個特徵。 稀疏性也影響倒排索引(用於索引text/keyword欄位)和維度點(用於索引geo_point和numerics型別)的效率,但程度較小。

以下是一些有助於避免稀疏性的建議:

5.1避免將不相關的資料放在同一個索引

您應該避免將具有完全不同結構的文件放入同一索引中以避免稀疏性。 將這些文件放入不同的索引通常會更好,您還可以考慮為這些較小的索引提供較少的分片,因為它們總體上包含的文件較少。

請注意,此建議不適用於您需要在文件之間使用父/子關係的情況,因為此功能僅在位於同一索引中的文件上受支援。

5.2規範化文件結構

即使你真的需要在同一個索引中放入不同型別的文件,也許有機會減少稀疏性。 例如,如果索引中的所有文件都有一個時間戳欄位,但有些文件稱之為timestamp,而其他文件稱之為creation_date,則有助於重新命名它,以便所有文件對同一資料具有相同的欄位名稱。

5.3避免使用types

型別可能聽起來像是在單個索引中儲存多種型別資料(意譯)的好方法。 其實它們不是!假設types將所有內容儲存在單個索引中,基於上述稀疏性的討論,在單個索引中具有不同欄位的多個型別會有問題。

如果您的type沒有非常相似的Mappings,您可能需要考慮將它們移動到專用索引。

5.4在稀疏欄位上禁用norms和doc_values

如果上述建議均不適用於您的情況,您可能需要檢查在稀疏欄位中是否確實需要norms和doc_values。 如果在欄位上不需要生成計算分數,則可以禁用norms,對於僅用於過濾的欄位通常也是如此。 可以在既不用於排序也不用於聚合的欄位上禁用doc_values。 請注意,不應輕易做出這個決定,因為這些引數不能在實時索引上更改,因此如果您意識到需要norms或doc_values,則必須重新reindex索引。

【銘毅天下註解】
1)6.X以後就不存在一個索引多個type了,一個索引下只有唯一的type了。所以:5.X版本之前的多type要變成多索引。
2)建立索引的時候,Mapping的設計非常重要,各個欄位的細分設計一方面決定了儲存,另一方面:不同欄位型別的設計會對效能產生非常重要的影響。

這裡寫圖片描述
打造Elasticsearch基礎、進階、實戰第一公眾號!