一、引言
Elasticsearch是很是靈活且功能豐富的搜索引擎,它提供了許多不一樣查詢數據的方法。在實戰業務場景中,常常會出現遠遠低於預期查詢速度的慢查詢。做爲分佈式系統的Elasticsearch,可能有各類影響查詢性能的因素,包括外部因素,如負載均衡設置,網絡延遲(帶寬,NIC卡/驅動程序)等。
本文主要討論可能致使慢查詢的緣由以及如何在Elasticsearch的上下文中識別它們?
本文主要源於常見慢查詢故障的排除方法,閱讀本文的前提須要你對Elasticsearch的原理有大體的瞭解。
若是不瞭解Elastic相關原理,能夠移步:elastic.blog.csdn.net 或 歷史文章。
若是不瞭解慢查詢,能夠移步:爲何Elasticsearch查詢變得這麼慢了?
本文的目的:根治慢查詢。
二、Elasticsearch慢查詢六大症狀及解決方案
在咱們研究一些棘手的案例以前,讓咱們從一些最多見的慢查詢及其解決方案開始。
2.1 症狀1:非活動(檢索/寫入)狀態資源利用率也很是高
症狀詳情:每一個分片都消耗資源(CPU /內存)。即便沒有索引/搜索請求,分片的存在也會消耗集羣開銷。
2.1.1 問題描述
集羣中的分片太多,以致於任何查詢執行起來都很慢。一個好的經驗法則——確保每一個節點的非凍結分片數量保持在:20如下/每GB堆內存。
2.1.2 解決方案
一、部署以前,設計先行。
正如VIVO搜索技術總監振濤兄所說:「集羣規劃核心是容量預估,就比如你建個樓,必須規劃好容量,否則說用多少就建多高,吃在地基撐不住!!」。
任何部署的良好開端都是執行適當的容量規劃,以幫助肯定每一個搜索用例的最佳分片數。
二、減小分片數,實施凍結索引或添加其餘節點以實現負載均衡。
三、考慮冷熱數據分離架構(適用於基於時間的索引)以及Elasticsearch中的翻轉索引(rollover)/壓縮索引(shrink)功能,以有效管理分片計數。
推薦閱讀:我在 Elasticsearch 集羣內應該設置多少個分片?
https://www.elastic.co/cn/blog/how-many-shards-should-i-have-in-my-elasticsearch-cluster
Elasticsearch5.x冷熱架構實現
https://www.elastic.co/cn/blog/hot-warm-architecture-in-elasticsearch-5-x
容量規劃最佳實踐(必讀)
https://www.elastic.co/guide/en/elasticsearch/guide/master/capacity-planning.html
2.2 症狀2:線程池存在大量rejected
搜索線程池顯示「拒絕」計數的持續增長,該計數基於上次羣集從新啓動而累積。
1GET / _cat / thread_pool / search?v&h = node_name,name,active,rejected,completed
響應以下:
1node_name name active rejected completed
2instance-0000000001 search 0 10 0
3instance-0000000002 search 0 20 0
4instance-0000000003 search 0 30 0
2.2.1 問題描述
場景1:查詢的目標是太多分片,超過集羣中的CPU核數。這會在搜索線程池中建立排隊任務,從而致使搜索拒絕。
場景2:磁盤I/O速度慢或在某些狀況下徹底飽和的CPU致使搜索排隊。
2.2.2 解決方案
一、建立索引時採用1主分片&1副本模型。
使用索引模板是在建立索引階段作好設置是個好方法。(7.0及更高版本默認1主1副)。
二、 Elasticsearch 5.1或更高版本支持搜索任務取消,這對於取消顯示在任務管理API中慢查詢任務很是有用。
任務管理:
1GET _tasks?nodes=nodeId1,nodeId2
取消任務
1POST _tasks/oTUltX4IQMOUUVeiohTt8A:12345/_cancel
三、要改進磁盤I / O,請查看咱們的存儲建議,並確保使用推薦的硬件以得到最佳性能。
存儲優化建議:
https://www.elastic.co/guide/en/elasticsearch/reference/7.0/tune-for-indexing-speed.html#_use_faster_hardware
2.3 症狀3:高CPU和索引化延遲
當集羣不堪重負時,度量標準關聯顯示CPU利用率高和索引化延遲大(以下圖)。
html
Metric指標Kibana覈查方法:
https://www.elastic.co/guide/en/kibana/7.0/elasticsearch-metrics.html
2.3.1 問題描述
寫入數據量大(索引化)會影響搜索性能。
2.3.2 解決方案
一、調大刷新頻率
將index.refresh_ interval(文檔被索引到數據搜索可見時間間隔)增長到 30 s,一般有助於提升索引性能。
實戰中要結合具體業務場景,可能會有所不一樣,所以測試是關鍵。這樣避免了缺省一秒生成一個分段的麻煩。
二、對於重型索引用例,請檢查咱們的索引調整建議,以優化索引和搜索性能。
包含但不限於:
1)數據初始化階段refresh設置 -一、副本設置爲 0,以提高寫入速度;寫入完畢後復原。
2)關閉swapping。
3)使用文件系統緩存。
4)使用自動生成ID。
性能調優實踐:
https://www.elastic.co/guide/en/elasticsearch/reference/7.0/tune-for-indexing-speed.html#_disable_refresh_and_replicas_for_initial_loads
2.4 症狀4:副本增長後延時增大
在增長副本分片計數(例如,從1到2)以後能夠觀察到查詢等待時間。若是存在更多數據,則緩存的數據將很快被逐出,致使操做系統層面頁面錯誤增長。
2.4.1 問題描述
文件系統緩存沒有足夠的內存來緩存常常查詢的索引部分。
Elasticsearch的查詢緩存實現了LRU置換算法:當緩存變滿時,最近最少使用的數據被置換以便爲新數據騰出空間。
請求緩存:
https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-cache.html
2.4.2 解決方案
一、爲文件系統緩存留出至少 50 %的物理RAM。
內存越多,能夠緩存的越多,尤爲是在集羣遇到I / O問題時。假設堆大小已正確配置,剩下的任何可用於文件系統緩存的剩餘物理RAM均可以大大加快搜索性能。
堆內存大小配置建議:Min(32 GB,物理機器內存 / 2)。
例如,128 GB內存服務器爲堆提供 30GB空間,爲文件系統緩存(有時稱爲OS緩存)留出剩餘內存,假設操做系統緩存最近訪問的4KB數據塊,若是你再一次讀取相同的文件,不須要花很長時間去磁盤上讀,直接在內存上讀來的更快。
二、使用query緩存和request緩存加快檢索速度。
節點級別的query緩存默認是開啓的。對應配置:
1index.queries.cache.enabled
請求緩存默認是開啓的,若是被強制關閉了,能夠動態設置開啓。
1PUT /my_index/_settings
2{ "index.requests.cache.enable": true }
三、使用preference優化高速緩存
可使用搜索請求首選項preference來優化全部這些高速緩存。以便每次將某些搜索請求路由到同一組分片,而不是在可用的不一樣副本之間交替。
這將更好地利用請求緩存、節點查詢緩存和文件系統緩存。
2.5 症狀5:共享硬件資源時的高資源利用率。
操做系統顯示始終較高的CPU 、磁盤、I / O使用率。
中止第三方應用程序後能夠看到性能提高。
2.5.1 問題描述
其餘進程(例如Logstash)和Elasticsearch自己之間存在資源(CPU、內存、或磁盤I / O)爭用。
2.5.2 解決方案
給Elasticsearch隔離的硬件環境或虛擬環境。
避免在共享硬件上與其餘資源密集型應用程序一塊兒運行Elasticsearch。
2.6 症狀6:聚合N多惟一值引發的高內存使用率
查詢包含惟一值(例如,ID,用戶名,電子郵件地址等)的聚合字段時性能不佳。
在堆內存分析時發現:Java對象使用"search", "buckets", "aggregation"等術語,消耗大量的堆內存。
2.6.1 問題緣由
聚合在高基數(high-cardinality)字段上運行,須要大量資源來獲取許多存儲桶。
還能夠存在涉及nested字段和/或join字段的嵌套聚合。
註解:high-cardinality中文解讀爲高基數很差理解。舉個例子:
高基數——列中有不少惟一值(),如主鍵
低基數——與之相反,如性別列(只有男、女)。
2.6.2 解決方案
一、要提升高基數term聚合的性能,推薦閱讀:
https://www.elastic.co/cn/blog/improving-the-performance-of-high-cardinality-terms-aggregations-in-elasticsearch
核心:使用eager_global_ordinals: true 提高性能。
二、有關進一步調整,請查看官網nested字段類型和join字段類型的使用建議,以更好地提升聚合性能。
3 偶發慢查詢解決方案
通常而言,偶爾或間歇性慢查詢能夠從官網的優化索引、優化檢索建議中中受益。
3.1 偶發慢查詢關聯監控指標
偶發慢查詢應與這些監控指標中的一個或多個密切相關:
1)CPU負載
2)索引吞吐量
3)搜索吞吐量
4)垃圾收集(GC)活動
5)搜索線程池隊列大小
線程池查看方法:
1GET /_cat/thread_pool
3.2 ARS提高檢索吞吐率
Elasticsearch還有另外一個有用的功能,稱爲自適應副本選擇(ARS),它容許協調節點了解數據節點上的負載,並容許它選擇最佳的分片副原本執行搜索,從而提升搜索吞吐量、下降延遲。
經過在查詢時間內更均勻地分散負載,ARS能夠對偶爾的減速有很大幫助。
在Elasticsearch 7.0及更高版本中,默認狀況下將啓用ARS。
4 非偶發慢查詢解決方案
對於非偶發慢查詢的場景,咱們能夠嘗試逐個刪除查詢中的功能,並檢查查詢是否仍然很慢。
4.1 「拆解DSL」排查慢查詢根源
查找最簡單查詢以重現性能問題有助於隔離和識別問題:
1)沒有高亮顯示它仍然很慢嗎?
2)沒有聚合,它仍然很慢嗎?
3)若是size設置爲0,它仍然很慢嗎?
當size設置爲0時,Elasticsearch會緩存搜索請求的結果,以便更快地進行搜索
4.2 參考官方搜索優化建議,看是否湊效?
https://www.elastic.co/guide/en/elasticsearch/reference/7.0/tune-for-search-speed.html
4.3 慢查詢排除實踐
1)啓用"profile:true"。
1GET /twitter/_search
2{
3 "profile": true,
4 "query" : {
5 "match" : { "message" : "some number" }
6 }
7}
2)查看節點的熱點線程。
這有助於瞭解CPU時間的使用狀況。
1GET /_nodes/hot_threads
3)使用kibana可視化profile分析工具
https://www.elastic.co/guide/en/kibana/7.0/xpack-profiler.html
5 捕獲慢查詢、耗費資源查詢
5.1 慢查詢、耗費資源查詢難捕獲
在Elasticsearch中同時處理不一樣的請求/線程時,很難捕獲慢查詢、耗費資源查詢。
實際N多人應用的業務場景,當沒法定位耗費資源查詢的用戶時,狀況變得更加複雜,這些查詢會下降集羣性能(例如,長垃圾收集(GC)週期)或更糟糕的是內存不足(OOM)狀況。
在Elasticsearch 7.0版中,咱們引入了一種新的內存熔斷策略,用於在保留內存時測量實際堆內存使用狀況。
此新策略可提升節點對資源耗費高查詢致使集羣過載的彈性支持,並在默認狀況下處於打開狀態,並可以使用新的集羣設置:
indices.breaker.total.use_real_memory 進行控制。
內存熔斷策略推薦:
https://github.com/elastic/elasticsearch/pull/31767
5.2 dump堆內存分析
以上方案並未覆蓋所有業務場景。藉助dump文件有助於更好地理解根本緣由。
在JVM OOM後Dump操做實戰參考:
https://www.elastic.co/guide/en/elasticsearch/reference/7.0/heap-dump-path.html
Linux捕獲dump文件的方法
1ps -ef|egrep 'elasticsearch|logstash' | grep -v grep
5.3 Elasticsearch的保護設置
Elasticsearch具備另外一個保護設置(最大桶search.max_buckets限制),以保護集羣出現OOM。
當超過桶的數量(在版本7.0中默認爲10,000)時(例如,當運行多層聚合時),
該最大桶聚合設置中止執行而且使搜索請求失敗。
5.4 斷路器設置
爲了進一步識別潛在的耗費資源的查詢,咱們能夠設置斷路器(indices.breaker.request.limit)。
設置方法:逐步縮放查詢範圍,從低閾值開始隔離查詢並逐漸向上移動閾值以縮小到特定的查詢。
斷路器設置參考:
https://www.elastic.co/guide/en/elasticsearch/reference/7.0/circuit-breaker.html#request-circuit-breaker
5.5 慢日誌分析
能夠經過啓用Elasticsearch中的慢速日誌來識別運行緩慢的查詢。
Slowlogs專門用於分片級別,這意味着只應用數據節點。
僅協調 Coordinating-only/客戶client節點不具有慢日誌分析功能,由於它們不保存數據(索引/分片)。
Slowlogs有助於回答如下問題:
1)查詢須要多長時間?
2)查詢請求正文的內容是什麼?
Slowlogs輸出舉例:
1[2019-02-11T16:47:39,882][TRACE][index.search.slowlog.query] [2g1yKIZ] [logstash-20190211][4] took[10.4s], took_millis[10459], total_hits[16160], types[], stats[],
2search_type[QUERY_THEN_FETCH], total_shards[10], source[{"size":0,"query":{"bool":{"must":[{"range":{"timestamp":{"from":1549266459837,"to":1549871259837,"include_lower":true,
3"include_upper":true,"format":"epoch_millis","boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}},"_source":{"includes":[],"excludes":[]},"stored_fields":"*","docvalue_fields":
4[{"field":"timestamp","format":"date_time"},{"field":"utc_time","format":"date_time"}],"script_fields":{"hour_of_day":{"script":{"source":"doc['timestamp'].value.getHourOfDay()",
5"lang":"painless"},"ignore_failure":false}},"aggregations":{"maxAgg":{"max":{"field":"bytes"}},"minAgg":{"min":{"field":"bytes"}}}}], id[]],
Slowlog 日誌拆解:
日誌拆分項
描述
[2019-02-11T16:47:39,882]
檢索時間
[TRACE]
日誌級別
[index.search.slowlog.query]
屬於search的query階段慢日誌
[2g1yKIZ]
節點名稱
[logstash-20190211]
索引名稱
[4]
query執行的分片序號
took[10.4s]
在分片4所需的處理時間。注意:在查看慢速日誌時,咱們但願避免從不一樣的分片中添加全部時間,由於每一個分片可能並行執行。
took_millis[10459]
耗費時間(毫秒)
total_hits[16160]
命中數
search_type[QUERY_THEN_FETCH]
search類型(query_then_fetch)
total_shards[10]
索引的總分片大小
source[]
執行檢索的請求body體
5.6 日誌審計(高階功能,低版本非付費會員建議跳過)
擁有金牌會員或鉑金會員訂閱的客戶(包括Elastic安全功能)能夠打開審覈日誌以捕獲有關查詢的更多詳細信息。(用戶能夠開始爲期30天的試用版來測試Elastic安全功能。)
注意:6.8和7.1以後,基礎安全功能已免費。之上的高版本可使用該功能。低版本的非會員不建議使用。
審計日誌記錄有助於回答如下問題:
1)查詢是何時發生的?
2)誰執行了查詢?
3)查詢的內容是什麼?
咱們須要調整審覈設置,由於默認設置至關繁瑣:
1)啓用安全審計日誌:
在elasticsearch.yml中設置
xpack.security.audit.enabled:true。
2)在安全審計輸出中啓用日誌或索引:
在elasticsearch.yml中設置
xpack.security.audit.outputs:[logfile,index]。
出於故障排除的目的,咱們建議選擇logfile而不是索引,由於審計日誌記錄的詳細程度可能會對集羣性能形成沒必要要的壓力。
審計模式可能很是冗長,所以請在完成故障排除後將其關閉。
3)在事件列表中包含authentication_success訪問權限
在elasticsearch.yml中設置
xpack.security.audit.logfile.events.include: authentication_success
六、小結
本文翻譯自Elastic官方博文,添加了本身的實踐解讀和星球內部討論總結內容。
在本文中,咱們討論了慢查詢的常見緣由以及解決方案。咱們還討論了偶發慢查詢和非偶發慢查詢的解決方案。一般會將慢查詢視爲更普遍集羣性能出問題的典型症狀。
node
8月24日北京Meetup上medcl列舉了10個緣由升級7.X,若是你仍是6.X、5.X甚至更低版本,推薦升級。Elasticsearch7.X高級版本在搜索 qps 上提高很大,相同配置下慢查詢也還會有較大改善。
Elasticsearch性能優化非一朝一夕之功,「認準病根才能根除病痛」。git