Elasticsearch性能優化的最終目的:用戶體驗爽
。 關於爽的定義——著名產品人梁寧曾經說過「人在知足時候的狀態叫作愉悅,人不被知足就會難受,就會開始尋求。若是這我的在尋求中,能馬上獲得即時知足,這種感受就是爽!」。 Elasticsearch的爽點就是:快、準、全
! 關於Elasticsearch性能優化,阿里、騰訊、京東、攜程、滴滴、58等都有過不少深刻的實踐總結,都是很是好的參考。本文換一個思路,基於Elasticsearch的爽點
,進行性能優化相關探討。html
在業務初期,常常被問到的問題,要幾個節點的集羣,內存、CPU要多大,要不要SSD? 最主要的考慮點是:你的目標存儲數據量
是多大?能夠針對目標數據量反推節點多少。node
注意:Elasticsearch有三個警惕水位線,磁盤使用率達到85%、90%、95%。 不一樣警惕水位線會有不一樣的應急處理策略。 這點,磁盤容量選型中要規劃在內。控制在85%之下
是合理的。 固然,也能夠經過配置作調整。mysql
除非內存很是大。 舉例:普通服務器,安裝了ES+Mysql+redis,業務數據量大了以後,勢必會出現內存不足等問題。redis
Elasticsearch官方文檔確定推薦SSD
,考慮到成本的緣由。須要結合業務場景, 若是業務對寫入、檢索速率有較高的速率要求,建議使用SSD磁盤。 阿里的業務場景,SSD磁盤比機械硬盤的速率提高了5倍。 但要因業務場景而異。sql
官方建議:堆內存的大小是官方建議是:Min(32GB,機器內存大小/2)。 Medcl和wood大叔都有明確說過,沒必要要設置32/31GB那麼大,建議:熱數據設置:26GB,冷數據:31GB
。 整體內存大小沒有具體要求,但確定是內容越大,檢索性能越好。 經驗值供參考:天天200GB+增量數據的業務場景,服務器至少要64GB內存。 除了JVM以外的預留內存要充足,不然也會常常OOM。數據庫
CPU核數是和ESThread pool關聯的。和寫入、檢索性能都有關聯。 建議:16核+
。緩存
除非業務量級很是大,例如:滴滴、攜程的PB+的業務場景,不然基本不太須要跨集羣檢索。性能優化
ES內部維護集羣通訊,不是基於zookeeper的分發部署機制,因此,無需奇數
。 可是discovery.zen.minimum_master_nodes的值要設置爲:候選主節點的個數/2+1,纔能有效避免腦裂。服務器
集羣節點數:<=3,建議:全部節點的master:true, data:true。既是主節點也是路由節點。 集羣節點數:>3, 根據業務場景須要,建議:逐步獨立出Master節點和協調/路由節點。app
熱數據存儲SSD
和普通曆史數據存儲機械磁盤,物理上提升檢索效率。
Mysql等關係型數據庫要分庫、分表。Elasticserach的話也要作好充分的考慮。
建議根據業務場景進行存儲。 不一樣通道類型的數據要分索引存儲
。舉例:知乎採集信息存儲到知乎索引;APP採集信息存儲到APP索引。
建議根據數據量衡量。 經驗值:建議每一個分片大小不要超過30GB
。
建議根據集羣節點的個數規模,分片個數建議>=集羣節點的個數。 5節點的集羣,5個分片就比較合理。 注意:除非reindex操做,分片數是不能夠修改
的。
除非你對系統的健壯性有異常高的要求,好比:銀行系統。能夠考慮2個副本以上。 不然,1個副本足夠。 注意:副本數是能夠經過配置隨時修改
的。
即使你是5.X版本,考慮到將來版本升級等後續的可擴展性。 建議:一個索引對應一個type。6.x默認對應_doc,5.x你就直接對應type統一爲doc。
隨着業務量的增長,單一索引和數據量激增給的矛盾凸顯。 按照日期規劃索引是必然選擇。 好處1:能夠實現歷史數據秒刪。很對歷史索引delete便可。注意:一個索引的話須要藉助delete_by_query+force_merge操做,慢且刪除不完全。 好處2:便於冷熱數據分開管理,檢索最近幾天的數據,直接物理上指定對應日期的索引,速度快的一逼! 操做參考:模板使用+rollover API使用
。
ES不像mysql方面的更改索引名稱。使用別名就是一個相對靈活的選擇。
默認Mapping的字段類型是系統自動識別
的。其中:string類型默認分紅:text和keyword兩種類型。若是你的業務中不須要分詞、檢索,僅須要精確匹配,僅設置爲keyword便可。 根據業務須要選擇合適的類型,有利於節省空間和提高精度,如:浮點型的選擇。
常見的開源中文分詞器包括:ik分詞器、ansj分詞器、hanlp分詞器、結巴分詞器、海量分詞器、「ElasticSearch最全分詞器比較及使用方法」 搜索可查看對比效果。 若是選擇ik,建議使用ik_max_word。由於:粗粒度的分詞結果基本包含細粒度ik_smart的結果。
根據業務須要,若是須要基於時間軸作分析,必須date類型; 若是僅須要秒級返回,建議使用keyword
。
Elasticsearch近實時的本質是:最快1s寫入的數據能夠被查詢到。 若是refresh_interval
設置爲1s,勢必會產生大量的segment,檢索性能會受到影響。 因此,非實時的場景能夠調大,設置爲30s,甚至-1。
寫入前,副本數設置爲0, 寫入後,副本數設置爲原來值。
批量接口爲bulk,批量的大小要結合隊列的大小,而隊列大小和線程池大小、機器的cpu核數。
在Linux系統上,經過運行如下命令臨時禁用交換:
sudo swapoff -a
複製代碼
數據量級達到TB+甚至更高以後,wildcard在多字段組合的狀況下很容易出現卡死,甚至致使集羣節點崩潰宕機
的狀況。 後果不堪設想。 替代方案: 方案一:針對精確度要求高的方案:兩套分詞器結合,standard和ik結合,使用match_phrase檢索。 方案二:針對精確度要求不高的替代方案:建議ik分詞,經過match_phrase和slop結合查詢。
中文match匹配顯然結果是不許確
的。很大的業務場景會使用短語匹配「match_phrase"。 match_phrase結合合理的分詞詞典、詞庫,會使得搜索結果精確度更高,避免噪音數據。
對於不須要使用計算相關度評分的場景,無疑filter緩存機制
會使得檢索更快。 舉例:過濾某郵編號碼。
和mysql查詢同樣,業務開發中,select * 操做幾乎是沒必要須的。 同理,ES中,_source 返回所有字段也是非必須的。 要經過_source 控制字段
的返回,只返回業務相關的字段。 網頁正文content,網頁快照html_content相似字段的批量返回,可能就是業務上的設計缺陷。 顯然,摘要字段應該提早寫入,而不是查詢content後再截取處理。
分頁查詢使用:from+size; 遍歷使用:scroll; 並行遍歷使用:scroll+slice
。 斟酌集合業務選型使用。
聚合結果是不精確的。除非你設置size爲2的32次冪-1,不然聚合的結果是取每一個分片的Top size元素後綜合排序後的值。 實際業務場景要求精確反饋結果的要注意。 儘可能不要獲取全量聚合結果
——從業務層面取TopN聚合結果值是很是合理的。由於的確排序靠後的結果值意義不大。
聚合結果展現的時,勢必面臨聚合後分頁的問題,而ES官方基於性能緣由不支持聚合後分頁。 若是須要聚合後分頁
,須要自開發實現。包含但不限於: 方案一:每次取聚合結果,拿到內存中分頁返回。 方案二:scroll結合scroll after集合redis實現。
讓Elasticsearch作它擅長的事情,很顯然,它更擅長基於倒排索引進行搜索。 業務層面,用戶想最快速度看到本身想要的結果,中間的「字段處理、格式化、標準化」等一堆操做,用戶是不關注的。 爲了讓Elasticsearch更高效的檢索,建議: 1)要作足「前戲」 字段抽取、傾向性分析、分類/聚類、相關性斷定放在寫入ES以前的ETL階段進行; 2)「睡服」產品經理 產品經理基於各類奇葩業務場景可能會提各類無理需求。 做爲技術人員,要「通知以情曉之以理」,給產品經理講解明白搜索引擎的原理、Elasticsearch的原理,哪些能作,哪些真的「臣妾作不到
」。
實際業務開發中,公司通常要求又想馬兒不吃草,又想馬兒飛快跑
。 對於Elasticsearch開發也是,硬件資源不足(cpu、內存、磁盤都爆滿)幾乎沒有辦法提高性能的。 除了檢索聚合,讓Elasticsearch作N多相關、不相干的工做,而後得出結論「Elastic也就那樣慢,沒有想像的快」。 你腦海中是否也有相似的場景浮現呢? 提供相對NB的硬件資源、作好前期的各類準備工做、讓Elasticsearch輕裝上陣
,相信你的Elasticsearch也會飛起來!
來日咱們再相會......
推薦閱讀: 一、阿里:elasticsearch.cn/article/617… 二、滴滴:t.cn/EUNLkNU 三、騰訊:t.cn/E4y9ylL 四、攜程:elasticsearch.cn/article/620… 五、社區:elasticsearch.cn/article/620… 六、社區:elasticsearch.cn/article/708 七、社區:elasticsearch.cn/article/620…
Elasticsearch基礎、進階、實戰第一公衆號