如果您在針對_id主鍵或開啟fielddata的text類型字段做排序、聚合查詢、腳本查詢等操作時,遇到搜索結果返回慢、頁面加載延遲等體驗問題,可以優先根據本文查看fielddata內存使用情況,如果fielddata內存使用率較高,可以參考本文定位并解決該問題。
背景信息
大量Elasticsearch(ES)集群運維案例顯示,fielddata內存使用率越小越好,fielddata不需要占用明顯的堆內存。但在Elasticsearch(ES)運維場景中,經常會遇到fielddata內存使用率高,嚴重時導致整個集群不可用的監控場景。
問題場景
fieldata緩存主要包含field data和global ordinals,占用fielddata的業務場景主要包含:
前兩個場景占用fielddata緩存較多,且影響較大,請優先關注。
針對
_id
主鍵做排序、agg查詢和腳本查詢操作。解決方案:
Elasticsearch官方文檔中指出禁止對
_id
進行聚合、排序和腳本操作,建議將_id
數據復制到開啟doc_values
的字段進行對應操作。Kibana Discover通過
_id
查詢數據時,下拉提示功能會自動觸發聚合。建議在Kibana > StackManagement > 高級設置中關閉
filterEditor:suggestValues
,避免在Kibana中根據主鍵進行搜索時,執行大量_id
字段的聚合分析。
對開啟fielddata的text類型字段進行聚合、排序和腳本查詢操作。
解決方案:
text字段默認關閉fielddata,開啟后可進行聚合、排序和腳本查詢操作。如果加載高基數text字段,fielddata會占用大量的堆內存,并且堆內存占用是永久的,建議將字段類型改成keyword。
keyword和ip等類型的字段,進行terms aggregations和composite aggregations等查詢。
join字段的parent和child文檔aggregations。
問題排查
您可以通過高級監控報警、fielddata API和熱線程三種方式,查看fileddata內存使用率是否過高。
高級監控報警
阿里云Elasticsearch高級監控報警服務在社區版監控的基礎上擴展了更細粒度的監控,尤其對集群運維提供了非常大的幫助。
- 登錄阿里云Elasticsearch控制臺。
在左側導航欄,單擊高級監控報警。
在高級監控報警頁面,選擇 。
在默認基礎指標頁簽中,查看fielddata內存使用指標。
fielddata API
- 登錄目標阿里云Elasticsearch實例的Kibana控制臺,根據頁面提示進入Kibana主頁。登錄Kibana控制臺的具體操作,請參見登錄Kibana控制臺。說明 本文以阿里云Elasticsearch 7.10.0版本為例,其他版本操作可能略有差別,請以實際界面為準。
- 單擊右上角的Dev tools。
在Console頁簽中,執行以下命令,查看各個節點的fielddata內存占用情況(fielddata.memory_size)。
GET _cat/nodes?v&h=ip,heap.percent,heap.current,heap.max,ram.current,ram.percent,fielddata.memory_size
預期結果如下。
熱線程
通過線程分析當前集群正在處理哪類耗時任務,以便聚焦根因定位。
GET _nodes/hot_threads
通過以下結果可以看到,熱線程正在處理fielddata.ordinals.GlobalOrdinalsBuilder,即在構建全局序數。
問題分析
您可以通過fielddata API和日志兩種方式,分析導致fielddata內存占用高問題的原因。
fielddata API
執行以下命令,獲取占用fielddata內存占用高的字段,分析和業務的哪類查詢相關。
GET _cat/fielddata?v&s=size:desc
預期結果如下。
日志聚焦查詢
通過在阿里云Elasticsearch控制臺中分析實例慢日志,查看是否存在導致fielddata內存占用高問題的操作,詳細信息請參見查詢日志。例如以下日志中存在查詢時按照_id排序的操作,導致fielddata內存占用高。
解決方案
您可以通過以下方案,臨時解決fielddata內存占用高的問題:
通過_cache/clear指定fielddata,清理fielddata緩存。如果不指定,將清理所有緩存。
POST _cache/clear?fielddata=true
重要通過API清理緩存是一種臨時方案,請結合業務環境評估后操作。該操作會加長查詢耗時,消耗額外的計算資源,可能會加重集群服務壓力。
建議您從業務具體查詢角度進行優化,否則即使進行了清理操作,后續查詢壓力仍可能回升至較高水平。例如,_id的查詢場景,建議您新建一個字段,把數據寫入新字段,通過新字段做查詢。
強制重啟集群。
具體操作請參見重啟實例或節點。
說明因fielddata內存占用高,導致fielddata占用大量的堆內存且集群不可訪問時,建議優先選擇強制重啟集群,恢復集群可訪問狀態。