讓 Elasticsearch 飛起來!——效能優化實踐乾貨

銘毅天下發表於2019-01-01

0、題記

Elasticsearch效能優化的最終目的:使用者體驗

關於爽的定義——著名產品人樑寧曾經說過“人在滿足時候的狀態叫做愉悅,人不被滿足就會難受,就會開始尋求。如果這個人在尋求中,能立刻得到即時滿足,這種感覺就是爽!”。

Elasticsearch的爽點就是:快、準、全!

關於Elasticsearch效能優化,阿里、騰訊、京東、攜程、滴滴、58等都有過很多深入的實踐總結,都是非常好的參考。本文換一個思路,基於Elasticsearch的爽點,進行效能優化相關探討。

1、叢集規劃優化實踐

1.1 基於目標資料量規劃叢集

在業務初期,經常被問到的問題,要幾個節點的叢集,記憶體、CPU要多大,要不要SSD?

最主要的考慮點是:你的目標儲存資料量是多大?可以針對目標資料量反推節點多少。

1.2 要留出容量Buffer

注意:Elasticsearch有三個警戒水位線,磁碟使用率達到85%、90%、95%。

不同警戒水位線會有不同的應急處理策略。

這點,磁碟容量選型中要規劃在內。控制在85%之下是合理的。

當然,也可以通過配置做調整。

1.3 ES叢集各節點儘量不要和其他業務功能複用一臺機器。

除非記憶體非常大。

舉例:普通伺服器,安裝了ES+Mysql+redis,業務資料量大了之後,勢必會出現記憶體不足等問題。

1.4 磁碟儘量選擇SSD

Elasticsearch官方文件肯定推薦SSD,考慮到成本的原因。需要結合業務場景,如果業務對寫入、檢索速率有較高的速率要求,建議使用SSD磁碟。

阿里的業務場景,SSD磁碟比機械硬碟的速率提升了5倍。但要因業務場景而異。

1.5 記憶體配置要合理

官方建議:堆記憶體的大小是官方建議是:Min(32GB,機器記憶體大小/2)。

Medcl和wood大叔都有明確說過,不必要設定32/31GB那麼大,建議:熱資料設定:26GB,冷資料:31GB

總體記憶體大小沒有具體要求,但肯定是內容越大,檢索效能越好。

經驗值供參考:每天200GB+增量資料的業務場景,伺服器至少要64GB記憶體。除了JVM之外的預留記憶體要充足,否則也會經常OOM。

1.6 CPU核數不要太小

CPU核數是和ESThread pool關聯的。和寫入、檢索效能都有關聯。

建議:16核+

1.7 超大量級的業務場景,可以考慮跨叢集檢索

除非業務量級非常大,例如:滴滴、攜程的PB+的業務場景,否則基本不太需要跨叢集檢索。

1.8 叢集節點個數無需奇數

ES內部維護叢集通訊,不是基於zookeeper的分發部署機制,所以,無需奇數

但是discovery.zen.minimum_master_nodes的值要設定為:候選主節點的個數/2+1,才能有效避免腦裂。

1.9 節點型別優化分配

叢集節點數:<=3,建議:所有節點的master:true, data:true。既是主節點也是路由節點。 叢集節點數:>3, 根據業務場景需要,建議:逐步獨立出Master節點和協調/路由節點。

1.10 建議冷熱資料分離

熱資料儲存SSD和普通曆史資料儲存機械磁碟,物理上提高檢索效率。

2、索引優化實踐

Mysql等關係型資料庫要分庫、分表。Elasticserach的話也要做好充分的考慮。

2.1 設定多少個索引?

建議根據業務場景進行儲存。

不同通道型別的資料要分索引儲存。舉例:知乎採集資訊儲存到知乎索引;APP採集資訊儲存到APP索引。

2.2 設定多少分片?

建議根據資料量衡量。

經驗值:建議每個分片大小不要超過30GB

2.3 分片數設定?

建議根據叢集節點的個數規模,分片個數建議>=叢集節點的個數。

5節點的叢集,5個分片就比較合理。

注意:除非reindex操作,分片數是不可以修改的。

2.4副本數設定?

除非你對系統的健壯性有異常高的要求,比如:銀行系統。可以考慮2個副本以上。否則,1個副本足夠。

注意:副本數是可以通過配置隨時修改的。

2.5不要再在一個索引下建立多個type

即便你是5.X版本,考慮到未來版本升級等後續的可擴充套件性。

建議:一個索引對應一個type。6.x預設對應_doc,5.x你就直接對應type統一為doc。

2.6 按照日期規劃索引

隨著業務量的增加,單一索引和資料量激增給的矛盾凸顯。按照日期規劃索引是必然選擇。

好處1:可以實現歷史資料秒刪。很對歷史索引delete即可。注意:一個索引的話需要藉助delete_by_query+force_merge操作,慢且刪除不徹底。

好處2:便於冷熱資料分開管理,檢索最近幾天的資料,直接物理上指定對應日期的索引,速度快的一逼!

操作參考:模板使用+rollover API使用

2.7 務必使用別名

ES不像mysql方面的更改索引名稱。使用別名就是一個相對靈活的選擇。

3、資料模型優化實踐

3.1 不要使用預設的Mapping

預設Mapping的欄位型別是系統自動識別的。其中:string型別預設分成:text和keyword兩種型別。如果你的業務中不需要分詞、檢索,僅需要精確匹配,僅設定為keyword即可。

根據業務需要選擇合適的型別,有利於節省空間和提升精度,如:浮點型的選擇。

3.2 Mapping各欄位的選型流程

3.3 選擇合理的分詞器

常見的開源中文分詞器包括:ik分詞器、ansj分詞器、hanlp分詞器、結巴分詞器、海量分詞器、“ElasticSearch最全分詞器比較及使用方法” 搜尋可檢視對比效果。

如果選擇ik,建議使用ik_max_word。因為:粗粒度的分詞結果基本包含細粒度ik_smart的結果。

3.4 date、long、還是keyword

根據業務需要,如果需要基於時間軸做分析,必須date型別;如果僅需要秒級返回,建議使用keyword

4、資料寫入優化實踐

4.1 要不要秒級響應?

Elasticsearch近實時的本質是:最快1s寫入的資料可以被查詢到。

如果refresh_interval設定為1s,勢必會產生大量的segment,檢索效能會受到影響。

所以,非實時的場景可以調大,設定為30s,甚至-1。

4.2 減少副本,提升寫入效能。

寫入前,副本數設定為0,寫入後,副本數設定為原來值。

4.3 能批量就不單條寫入

批量介面為bulk,批量的大小要結合佇列的大小,而佇列大小和執行緒池大小、機器的cpu核數。

4.4 禁用swap

在Linux系統上,通過執行以下命令臨時禁用交換:

1sudo swapoff -a

5、檢索聚合優化實戰

5.1 禁用 wildcard模糊匹配

資料量級達到TB+甚至更高之後,wildcard在多欄位組合的情況下很容易出現卡死,甚至導致叢集節點崩潰當機的情況。

後果不堪設想。

替代方案:

方案一:針對精確度要求高的方案:兩套分詞器結合,standard和ik結合,使用match_phrase檢索。

方案二:針對精確度要求不高的替代方案:建議ik分詞,通過match_phrase和slop結合查詢。

5.2極小的概率使用match匹配

中文match匹配顯然結果是不準確的。很大的業務場景會使用短語匹配“match_phrase”。

match_phrase結合合理的分詞詞典、詞庫,會使得搜尋結果精確度更高,避免噪音資料。

5.3 結合業務場景,大量使用filter過濾器

對於不需要使用計算相關度評分的場景,無疑filter快取機制會使得檢索更快。

舉例:過濾某郵編號碼。

5.4控制返回欄位和結果

和mysql查詢一樣,業務開發中,select * 操作幾乎是不必須的。

同理,ES中,_source 返回全部欄位也是非必須的。

要通過_source 控制欄位的返回,只返回業務相關的欄位。

網頁正文content,網頁快照html_content類似欄位的批量返回,可能就是業務上的設計缺陷。

顯然,摘要欄位應該提前寫入,而不是查詢content後再擷取處理。

5.5 分頁深度查詢和遍歷

分頁查詢使用:from+size;
遍歷使用:scroll;
並行遍歷使用:scroll+slice

斟酌集合業務選型使用。

5.6 聚合Size的合理設定

聚合結果是不精確的。除非你設定size為2的32次冪-1,否則聚合的結果是取每個分片的Top size元素後綜合排序後的值。

實際業務場景要求精確反饋結果的要注意。
儘量不要獲取全量聚合結果——從業務層面取TopN聚合結果值是非常合理的。因為的確排序靠後的結果值意義不大。

5.7 聚合分頁合理實現

聚合結果展示的時,勢必面臨聚合後分頁的問題,而ES官方基於效能原因不支援聚合後分頁。

如果需要聚合後分頁,需要自開發實現。包含但不限於:

方案一:每次取聚合結果,拿到記憶體中分頁返回。

方案二:scroll結合scroll after集合redis實現。

6、業務優化

讓Elasticsearch做它擅長的事情,很顯然,它更擅長基於倒排索引進行搜尋。

業務層面,使用者想最快速度看到自己想要的結果,中間的“欄位處理、格式化、標準化”等一堆操作,使用者是不關注的。

為了讓Elasticsearch更高效的檢索,建議:

1)要做足“前戲”
欄位抽取、傾向性分析、分類/聚類、相關性判定放在寫入ES之前的ETL階段;

2)“睡服”產品經理
產品經理基於各種奇葩業務場景可能會提各種無理需求。

作為技術人員,要“通知以情曉之以理”,給產品經理講解明白搜尋引擎的原理、Elasticsearch的原理,哪些能做,哪些真的“臣妾做不到”。

7、小結

實際業務開發中,公司一般要求又想馬兒不吃草,又想馬兒飛快跑

對於Elasticsearch開發也是,硬體資源不足(cpu、記憶體、磁碟都爆滿)幾乎沒有辦法提升效能的。

除了檢索聚合,讓Elasticsearch做N多相關、不相干的工作,然後得出結論“Elastic也就那樣慢,沒有想像的快”。

你腦海中是否也有類似的場景浮現呢?

提供相對NB的硬體資源、做好前期的各種準備工作、讓Elasticsearch輕裝上陣,相信你的Elasticsearch也會飛起來!

推薦閱讀:

  • 1、阿里:https://elasticsearch.cn/article/6171
  • 2、滴滴:http://t.cn/EUNLkNU
  • 3、騰訊:http://t.cn/E4y9ylL
  • 4、攜程:https://elasticsearch.cn/article/6205
  • 5、社群:https://elasticsearch.cn/article/6202
  • 6、社群:https://elasticsearch.cn/article/708
  • 7、社群:https://elasticsearch.cn/article/6202

相關文章