本文首發於 vivo互聯網技術 微信公衆號 https://mp.weixin.qq.com/s/AAkVdzmkgdBisuQZldsnvg
英文原文: https://qbox.io/blog/elasticsearch-search-tuning-part-2
做者:Adam Vanderbush
譯者:楊振濤
目錄javascript
Elasticsearch搜索調優權威指南,是QBOX在其博客上發佈的系列文章之一,本文是該系列的第二篇,主要介紹了索引預處理、mapping創建、避免腳本的使用、索引段合併等搜索性能相關的調優方法。java
本文是Elasticsearch搜索調優系列文章3篇中的第2篇,第1篇參考這裏(點擊)。本系列教程旨在更進一步討論針對Elasticsearch 5.0及以上版本的搜索調優技術、策略及建議。數據庫
爲了優化數據的索引方式,應當在查詢中預置一些模式。好比,若是全部文檔都有一個叫 price 的價格字段,而且大部分查詢在一個固定範圍列表上執行 range 聚合,那麼就能夠經過預索引範圍到索引中並使用一個 terms 聚合,來加速該聚合。json
好比有以下文檔:segmentfault
curl -XPUT 'ES_HOST:ES_PORT/index/type/1 ?pretty' -H 'Content-Type: application/json' -d '{ "designation": "bowl", "price": 13 }'
以及以下搜索請求:安全
curl -XGET 'ES_HOST:ES_PORT/index/_search ?pretty' -H 'Content-Type: application/json' -d '{ "aggs": { "price_ranges": { "range": { "field": "price", "ranges": [ { "to": 10 }, { "from": 10, "to": 100 }, { "from": 100 } ] } } } }'
而後就能夠在索引階段增長一個 price_range 字段,該字段應該映射爲一個關鍵字:微信
curl -XPUT 'ES_HOST:ES_PORT/index ?pretty' -H 'Content-Type: application/json' -d '{ "mappings": { "type": { "properties": { "price_range": { "type": "keyword" } } } } }' curl -XPUT 'ES_HOST:ES_PORT/index/type/1 ?pretty' -H 'Content-Type: application/json' -d '{ "designation": "bowl", "price": 13, "price_range": "10-100" }'
接下來搜索請求就能聚合這個新的字段,而不是在 price 字段上執行一個範圍聚合。app
curl -XGET 'ES_HOST:ES_PORT/index/_search ?pretty' -H 'Content-Type: application/json' -d '{ "aggs": { "price_ranges": { "terms": { "field": "price_range" } } } }'
事實上,一些數值型的數據,並不意味着老是要被映射爲一個數值型字段。典型的,那些存儲爲諸如 ISBN 之類的標識符,或者任何標識另外一個數據庫中記錄的數字的字段,可能映射爲關鍵字比映射爲一個 integer 或 long 類型更好。less
關鍵字類型用於索引結構化內容,好比 email 地址、主機名稱、狀態碼、郵政編碼或標籤。curl
典型地用於過濾(好比查找全部已發佈的博客文章)、排序以及聚合。關鍵字字段只可經過其精確值搜索獲得。
若是須要索引全文內容好比 email 內容或產品描述,可能就要使用一個文本字段。
下面是一個關鍵字字段映射的示例:
curl -XPUT 'ES_HOST:ES_PORT/my_index ?pretty' -H 'Content-Type: application/json' -d '{ "mappings": { "my_type": { "properties": { "tags": { "type": "keyword" } } } } }'
從 2.x 版本導入的索引是不支持關鍵字的;相反,它們會試圖把 keyword 類型降級爲 string 類型。這支持合併新的映射和舊的映射。長期存在的索引,必須在升級到6.x 版本前重建,可是映射降級提供了按本身的計劃實施重建的機會。
通常來講要儘可能避免使用腳本;若是必需要使用,優先選擇 Painless 和表達式引擎。
Painless 是一門簡單安全的腳本語言,專門爲在 Elasticsearch 中使用而設計,是 Elasticsearch 的默認腳本語言,可安全地用於內聯和存儲腳本。關於 Painless 語法和語言特性的更詳細描述,請參考 Painless 語言規範。
請參考 「 Painless Scripting in Elasticsearch 」 更深刻地瞭解 Painless 腳本語言指南。
Lucene 表達式會把一個 javascript 表達式編譯爲字節碼,設計用於高性能自定義評級和排序函數,並支持 inline 和默認的存儲腳本。
表達式相對於自定義 Lucene 代碼而言,有着更好的性能表現;其性能相對其餘腳本引擎有更低的單文檔成本:表達式更加「領先」。
這就容許很是快的執行,尤爲是比本身寫的本地腳本快不少。
表達式支持一個 javascript 語法子集:一個單獨的表達式。參見表達式模塊的文檔,瞭解支持的操做符和函數。
表達式腳本中可訪問的變量有:
表達式腳本能夠用於script_score、script_fields、排序腳本以及數值型聚合腳本,只要簡單地設置參數到表達式中便可。
只讀索引在合併爲單一的段後將會很是受益。典型的狀況是基於時間的索引:只有當前時間窗的索引會成爲新文檔,同時舊索引成爲只讀。
強制合併 API 支持經過 API 強制合併一個或更多的索引。合併與每一個分片中 Lucene索引的段數量有關。強制合併操做支持經過合併來減小段數量。
該調用在合併完成以前將會處於阻塞狀態。若是 http 鏈接斷掉,請求將在後臺繼續,在前一個強制合併完成以前,全部新請求將會阻塞。
curl _XPOST 'ES_HOST:ES_POST/twitter/_forcemer ge?pretty'
強制合併 API 接受下列請求參數:
更多內容敬請關注 vivo 互聯網技術 微信公衆號
注:轉載文章請先與微信號:labs2020 聯繫。