1. 程式人生 > >Elasticsearch聚合優化 | 聚合速度提升5倍

Elasticsearch聚合優化 | 聚合速度提升5倍

question 線性 方式 文章 arc 百萬 hint desc quest

https://blog.csdn.net/laoyang360/article/details/79253294

1、聚合為什麽慢?
大多數時候對單個字段的聚合查詢還是非常快的, 但是當需要同時聚合多個字段時,就可能會產生大量的分組,最終結果就是占用 es 大量內存,從而導致 OOM 的情況發生。
實踐應用發現,以下情況都會比較慢:
1)待聚合文檔數比較多(千萬、億、十億甚至更多);
2)聚合條件比較復雜(多重條件聚合);
3)全量聚合(翻頁的場景用)。

2、聚合優化方案探討
優化方案一:默認深度優先聚合改為廣度優先聚合。
"collect_mode" : "breadth_first"
1
depth_first 直接進行子聚合的計算
breadth_first 先計算出當前聚合的結果,針對這個結果在對子聚合進行計算。
優化方案二: 每一層terms aggregation內部加一個 “execution_hint”: “map”。
"execution_hint": "map"
1
國內解釋最詳細的版本來自Wood大叔:

Map方式的結論可簡要概括如下:
1)查詢結果直接放入內存中構建map,在查詢結果集小的場景下,速度極快;
2)但如果待結果集合很大的情況,map方式不一定也快。

3、做個實驗
聚合的平衡點是多少呢?

3.1 實驗場景
場景一:在近億的document中,檢索滿足給定條件的數據,並對聚合結果全量聚合。
場景二:在百萬級別的document中,全量聚合。
場景三:在近億級別的document中,全量聚合。

3.2 聚合操作
POST index_*/_search
{
"sort": [
{
"nrply": "desc"
}
],
"aggs": {
"count_ix": {
"terms": {
"field": "ix_id",
"execution_hint": "map",

"size": 1000,
"collect_mode": "breadth_first"
}
}

},
"size":0
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1)修改索引名稱,以獲取更多的文檔。
2)map模式添加 “execution_hint”: “map”,默認是global_ordinals模式。
3)”size”: 1000,設定聚合取值。

3.3 聚合結果


3.4 結果分析
對比場景一與場景二、三,說明:
1)當結果集合比較少的時候,map聚合方式明顯速度更快,速度提升了接近5倍!
2)當結果集合比較大的時候(百萬——億級別)的時候,傳統的聚合方式會比map方式快。

4、小結
1)global_ordinals是關鍵字字段( keyword field )的默認選項,它使用 全局順序(global ordinals) 來動態分配存儲區,因此內存使用情況與作為聚合作用域一部分的文檔值的數量成線性關系。

2)只有極少數文檔與查詢匹配匹配時才應考慮使用map方式。
默認情況下,只有在腳本上運行聚合時才會使用map,因為它們沒有序號( ordinals )。

否則,基於 順序(ordinals) 的執行模式會相對更快。

參考:
http://t.cn/R8WI6QD
http://t.cn/R8WIKta
https://elasticsearch.cn/question/1008
http://t.cn/R8WIpYn
---------------------
作者:銘毅天下
來源:CSDN
原文:https://blog.csdn.net/laoyang360/article/details/79253294
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

Elasticsearch聚合優化 | 聚合速度提升5倍