Elasticsearch學習之深入聚合分析五---案例實戰
1. fielddata核心原理
fielddata加載到內存的過程是lazy加載的,對一個analzyed field執行聚合時,才會加載,而且是field-level加載的,一個index的一個field,所有doc都會被加載,而不是少數doc,不是index-time創建,是query-time創建
2. fielddata內存限制
indices.fielddata.cache.size: 20%,超出限制,清除內存已有fielddata數據,fielddata占用的內存超出了這個比例的限制,那麽就清除掉內存中已有的fielddata數據,默認無限制,限制內存使用,但是會導致頻繁evict和reload,大量IO性能損耗,以及內存碎片和gc
3. 監控fielddata內存使用
GET /_stats/fielddata?fields=*
GET /_nodes/stats/indices/fielddata?fields=*
GET /_nodes/stats/indices/fielddata?level=indices&fields=*
4. circuit breaker
如果一次query load的feilddata超過總內存,就會oom --> 內存溢出
circuit breaker會估算query要加載的fielddata大小,如果超出總內存,就短路,query直接失敗
indices.breaker.fielddata.limit:fielddata的內存限制,默認60%
indices.breaker.request.limit:執行聚合的內存限制,默認40%
indices.breaker.total.limit:綜合上面兩個,限制在70%以內
5. fielddata預加載
如果真的要對分詞的field執行聚合,那麽每次都在query-time現場生產fielddata並加載到內存中來,速度可能會比較慢
POST /test_index/_mapping/test_type { "properties": { "test_field": { "type": "string", "fielddata": { "loading" : "eager" } } } }
query-time的fielddata生成和加載到內存,變為index-time,建立倒排索引的時候,會同步生成fielddata並且加載到內存中來,這樣的話,對分詞field的聚合性能當然會大幅度增強
6. fielddata 序號標記預加載
global ordinal原理解釋
doc1: status1
doc2: status2
doc3: status2
doc4: status1
有很多重復值的情況,會進行global ordinal標記
status1 --> 0
status2 --> 1
doc1: 0
doc2: 1
doc3: 1
doc4: 0
建立的fielddata也會是這個樣子的,這樣的好處就是減少重復字符串的出現的次數,減少內存的消耗
POST /test_index/_mapping/test_type { "properties": { "test_field": { "type": "string", "fielddata": { "loading" : "eager_global_ordinals" } } } }
Elasticsearch學習之深入聚合分析五---案例實戰