ElasticSearch性能優化主要分為4個方面的優化。
一、服務器部署
二、服務器配置
三、數據結構優化
四、運行期優化
一、服務器部署
1、增加1-2台服務器,用於負載均衡節點
elasticSearch的配置文件中有2個參數:node.master和node.data。這兩個參 數搭配使用時,能夠幫助提供服務器性能。
1.1> node.master: false node.data: true
該node服務器只作為一個數據節點,只用於存儲索引數據。使該node服務器功能 單一,只用於數據存儲和數據查詢,降低其資源消耗率。
1.2> node.master: true node.data: false
該node服務器只作為一個主節點,但不存儲任何索引數據。該node服務器將使用 自身空閑的資源,來協調各種創建索引請求或者查詢請求,講這些請求合理分發到相關 的node服務器上。
1.3> node.master: false node.data: false
該node服務器即不會被選作主節點,也不會存儲任何索引數據。該服務器主要用 於查詢負載均衡。在查詢的時候,通常會涉及到從多個node服務器上查詢數據,並請 求分發到多個指定的node服務器,並對各個node服務器返回的結果進行一個匯總處理, 最終返回給客戶端。
2、關閉data節點服務器中的http功能
針對ElasticSearch集群中的所有數據節點,不用開啟http服務。將其中的配置 參數這樣設置:http.enabled: false,同時也不要安裝head, bigdesk, marvel等監控 插件,這樣保證data節點服務器只需處理創建/更新/刪除/查詢索引數據等操作。
http功能可以在非數據節點服務器上開啟,上述相關的監控插件也安裝到這些服 務器上,用於監控ElasticSearch集群狀態等數據信息。
這樣做一來出於數據安全考慮,二來出於服務性能考慮。
3、一台服務器上最好只部署一個Node
一台物理服務器上可以啟動多個Node服務器節點(通過設置不同的啟動port), 但一台服務器上的CPU,內存,硬盤等資源畢竟有限,從服務器性能考慮,不建議一台 服務器上啟動多個node節點。
二、服務器配置
1、配置索引線程池的大小
ElastiSearch服務器有多個線程池大小配置。主要有:index,search,suggest, get,bulk,percolate,snapshot,snapshot_data,warmer,refresh。
在此主要針對index和search進行一個配置調整。index操作包含:創 建/更新/刪除索引數據。search操作主要針對用戶的各種搜索操作。
具體配置如下:
threadpool:
index:
type: fixed
size: 100
search:
type: fixed
size: 1000
2、創建/查找索引設置相同的分詞解析器
索引服務器用到了ik中文分詞插件,對於添加到該搜索服務器中的數據都使用該 中文分詞(例如orgglobal對象中的orgName就使用了ik中文分詞)。當執行搜索請求 時,搜索關鍵詞也需要用到相關的中文分詞器,如果不指定設置的話,則會使用服務器 默認的中文分詞standard,而使用standard作為中文分詞器進行查詢時,性能不好。 通過將ik中分詞設置為默認的分詞器時,則查詢效率是standard的2-3倍。
該配置具體如下:
index:
analysis:
analyzer:
ik:
alias: [news_analyzer_ik,ik_analyzer]
type: org.elasticsearch.index.analysis.IkAnalyzerProvider
index.analysis.analyzer.default.type: ik
3、確定分片(shard)的數量和副本(replica)的數量
ElasticSearch在創建索引數據時,最好指定相關的shards數量和replicas,
否則會使用服務器中的默認配置參數shards=5,replicas=1。
因為這兩個屬性的設置直接影響集群中索引和搜索操作的執行。假設你有足夠的
機器來持有碎片和副本,那么可以按如下規則設置這兩個值:
1) 擁有更多的碎片可以提升索引執行能力,並允許通過機器分發一個大型的索引;
2) 擁有更多的副本能夠提升搜索執行能力以及集群能力。
對於一個索引來說,number_of_shards只能設置一次,而number_of_replicas可以使用索引更新設置API在任何時候被增加或者減少。
這兩個配置參數在配置文件的配置如下:
index.number_of_shards: 5
index.number_of_shards: 1
4、查詢速度慢的日志配置
在進行實際應用中,會記錄下查詢速度慢或者添加索引速度慢的操作記錄,為后
續性能優化提供依據。其具體配置如下:
index.search.slowlog.threshold.query.warn: 10s
index.search.slowlog.threshold.query.info: 5s
index.search.slowlog.threshold.query.debug: 2s
index.search.slowlog.threshold.query.trace: 500ms
index.search.slowlog.threshold.fetch.warn: 1s
index.search.slowlog.threshold.fetch.info: 800ms
index.search.slowlog.threshold.fetch.debug: 500ms
index.search.slowlog.threshold.fetch.trace: 200ms
index.indexing.slowlog.threshold.index.warn: 10s
index.indexing.slowlog.threshold.index.info: 5s
index.indexing.slowlog.threshold.index.debug: 2s
index.indexing.slowlog.threshold.index.trace: 500ms
三、數據結構優化
1、盡量減少不需要的字段
ElasticSearch中存儲的數據是用於搜索服務,因此其他一些不需要用於搜索的字段最好不存到ES中,這樣即節省空間,同時在相同的數據量下,也能提高搜索性能。
2、routing值的設置
通常情況下,往ElasticSearch服務器添加索引數據時,是無需指定routing值。ElasticSearch會根據索引Id,將該條數據存儲到ElasticSearch集群中的一個shard中。而當指定了routing值為accountId(用戶Id),則ElasticSearch會將相同accountId的多個數據都存放到同一個shard中,后續查詢的時候,在指定routing值后,ElasticSearch只需要查詢一個shard就能得到所有需要的數據,而不用再去查詢所有的shard,從而大大提供了搜索性能。
四、運行期優化
1、optimize
隨着時間的推移,ElasicSearch中每個shard的數據也會越來越多,索引越來越大,而生成的segment(在每個shard中,每個索引文件實際是由多個sgment文件組成)也會越來越多。而segment越多的話,則查詢的性能越差,所以通過調用optimize命令,將多個segment合並成更少數量的segment(最少為一個),從而來提高查詢性能。
在調用該命令時,可以設置幾個參數,這些參數的具體含義如下:
1.1> max_num_segments
段數優化。要全面優化索引,將其設置為1。默認設置只需檢查是否需要執行一個合並,如果需要,則執行它。【經過測試,該值越小,查詢速度越快】
1.2> only_expunge_deletes
該優化操作是否只清空打有刪除標簽的索引記錄。在Lucence中,在執行刪除操作時,不會直接刪除segment中的記錄,而是對該記錄打上delete標簽。當多個segment進行合並操作時,就會生成一個新的segment,而該新的segment中不再包含刪除的記錄。這個參數允許只對哪些包含刪除記錄的segment進行優化操作。
1.3>flush
在執行完優化操作之后,再執行刷新操作。默認值為true
1.4>wait_for_merge
當該參數設置為true時,表示其他請求操作要等到合並segment操作結束之后,再進行響應。值得注意的是,由於這個優化操作是一個非常耗時,耗資源的事情,用戶提交的請求操作是不能容忍等待這么久,所以這個參數最好設置為false.
具體調用命令如下:
http://localhost:9200/indexName/_optimize?only_expunge_deletes=true&wait_for_merge=false
2、warmers
當ElasticSearch服務器啟動之后,業務系統中要使用的索引數據暫時沒有導入到內存中,因此當用戶進行第一次數據搜索時,會因為數據導入耗時很久,而嚴重影響用戶的使用體驗。為了解決該問題,可以使用warmer工具。通過ElastiSearch提供的工具,可以register/delete/get特定名稱的warmer。通常情況下,warmer包含的請求需要載入大量的索引數據(例如在數據搜索中需要針對特定字段的排序操作,或者用到一些聚合sum,min,max函數的查詢等),這樣才能達到預熱的效果。
具體調用示例如下(下面的warmer是針對索引名為test的warmer,warmer定義的名字為warmer_1):
curl -XPUT localhost:9200/test/_warmer/warmer_1 -d '{
"query" : {
"match_all" : {}
},
"aggs" : {
"aggs_1" : {
"terms" : {
"field" : "field"
}
}
}
}'
