背景
在使用elasticsearch時,如果使用了高基數的聚合查詢,有可能導致記憶體溢位OOM,導致elasticsearch的節點問題,進一步引發該節點上的分片漂移,從而影響線上的查詢問題,
原因
Elasticsearch在執行高基數查詢時,會默認為每組資料生成一個桶,并且存放在記憶體中,當基數很大也就是分組資料的重復性不高時,就會生成很多的桶,從而占用大量的記憶體,
記憶體使用介紹
ES的JVM heap按使用場景分為可GC部分和常駐部分, 可GC部分記憶體會隨著GC操作而被回收; 常駐部分不會被GC,通常使用LRU策略來進行淘汰; 記憶體占用情況如下圖:

1.common space
包括了indexing buffer和其他ES運行需要的class,indexing buffer由indices.memory.index_buffer_size引數控制, 默認最大占用10%,當full up后,該部分資料被刷入磁盤對應的Segments中,這部分空間是可以被回收反復利用的,
2.queryCache
node級別的filter過濾器結果快取,大小由indices.queries.cache.size 引數控制,默認10%,使用LRU淘汰策略,
3.requestCache
是shard級別的query result快取,通常 only requests of size 0 such as aggregations, counts and suggestions will be cached,使用LRU淘汰策略,通過indices.requests.cache.size引數控制,默認1%,設定后整個NODE都生效,
4.fieldDataCache
針對text欄位,沒有docValues屬性(相當于列存盤),當對text型別欄位進行sort,agg時,需要將對應的欄位內容全部加載到記憶體,這部分資料就放在fieldDataCache,通過indices.fielddata.cache.size 引數限制大小,默認不限制,這種情況下,占用記憶體會逐漸增多,直到觸發熔斷;新資料無法加載,
5.segmentsMemory
快取段資訊,包括FST,Dimensional points for numeric range filters,Deleted documents bitset ,Doc values and stored fields codec formats等資料,這部分快取是必須的,不能進行大小設定,通常跟index息息相關,close index、force merge均會釋放部分空間,
斷路器介紹及設定
ES通過斷路器的設定,來保護集群記憶體不超過設定值,從而保證集群的穩定性,
1.indices.breaker.fielddata.limit
fielddata斷路器默認設定堆的 40% 作為 fielddata 大小的上限,
2.indices.breaker.request.limit
request斷路器估算需要完成其他請求部分的結構大小,例如創建一個聚合桶,默認限制是堆記憶體的 60%,它實際上是node level的一個統計值,統計的是這個結點上,各類查詢聚合操作,需要申請的Bigarray的空間大小總和, 所以如果有一個聚合需要很大的空間,同時在執行的聚合可能也會被break掉,
3.indices.breaker.total.limit
父斷路器,保證inflight、request(agg)和fielddata的使用不會使用超過堆記憶體的限制,默認70%,
4.network.breaker.inflight requests.limit
限制當前通過HTTP等進來的請求使用記憶體不能超過Node記憶體的指定值,這個記憶體主要是限制請求內容的長度, 默認100%,
5.script.context.$CONTEXT.max_compilations_rate
特定時間間隔內允許為給定背景關系編譯的唯一動態腳本數的限制,默認為75/5m,即每5分鐘75次,
6.設定命令舉例:
{
'error': {
'type': 'circuit_breaking_exception',
'reason': '[parent] Data too large, data for [<http_request>] would be [123848638/118.1mb], which is larger than the limit of [123273216/117.5mb], real usage: [120182112/114.6mb], new bytes reserved: [3666526/3.4mb]',
'bytes_wanted': 123848638,
'bytes_limit': 123273216,
'durability': 'TRANSIENT'
},
'status': 429
}
效果演示
測驗節點配置128MB的JVM運行,父熔斷器設定為95%,即JVM使用達到117.5MB會觸發熔斷,然后不停的發出聚合請求,節點將回傳code 429,如下:
{
'error': {
'type': 'circuit_breaking_exception',
'reason': '[parent] Data too large, data for [<http_request>] would be [123848638/118.1mb], which is larger than the limit of [123273216/117.5mb], real usage: [120182112/114.6mb], new bytes reserved: [3666526/3.4mb]',
'bytes_wanted': 123848638,
'bytes_limit': 123273216,
'durability': 'TRANSIENT'
},
'status': 429
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/294154.html
標籤:其他
上一篇:Flink(四) 狀態管理 1
下一篇:ELK日志分析系統(未完...)
