ES group分组聚合的坑
參考鏈接:https://blog.csdn.net/u010454030/article/details/71762838
ES group分組聚合的坑
原來知道Elasticsearch在分組聚合時有一些坑但沒有細究,今天又看了遍順便做個筆記和大家分享一下。
我們都知道Elasticsearch是一個分布式的搜索引擎,每個索引都可以有多個分片,用來將一份大索引的數據切分成多個小的物理索引,解決單個索引數據量過大導致的性能問題,另外每個shard還可以配置多個副本,來保證高可靠以及更好的抗并發的能力。
將一個索引切分成多個shard,大多數時候是沒有問題的,但是在es里面如果索引被切分成多個shard,在使用group進行聚合時,可能會出現問題,這個在官網文檔里,描述也非常清楚
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#_shard_size_3
下面就針對官網的例子,描述下,group count如果有多個shard可能會出現的問題
假設我們現在,我們有一份商品的索引數據,它有3個shard,每個shard的數據如下所示:
現在我們的需求是,按商品分組求top5的商品,es收到這個請求后,會去搜索這三個shard,然后子每個shard上面取top5,數據如下圖所示:
最后,將三個shard的top5的數據,最后做一下匯聚然后最終排序取top5結果如下圖:
最后我們發現這個top5的結果,并不是100%精確的,只是一個近似精確的結果值:
Product A在所有top5的shard數據里面都存在,所以它的結果是精確的, Product C僅僅返回了 shard A 和 C里面的top5的數據,所以這里顯示50是不精確的, Product C在shard B里面也存在,但是它在 top5里面沒有出現,所以group后的結果實際上是有誤差的,再來看下 Product Z僅僅返回了2個shards的數據 因為第三個里面不存在,所以它的結果是準確的,最后我們注意下 Product H實際上它的總數是44,橫跨三個shard 但是它在每個shard的top5里面并沒有出現,所以最終的top5里面也沒有這條數據,這樣看來最終的top5的值并不是100% 準確的,這一點在設計和使用es的時候需要特別注意。
雖然我們可以調大返回size的個數來提高精確度,但是size個數的提升,也意味著有更多的數據會被返回,從而會導致檢索性能的下降,這一點是需要找到平衡點的。
那么有沒有方法避免這種不精確的統計的呢?
答案是有的,es官網文檔里面也提到,總共有2種:
第一種:
?聚合操作在單個shard時是精確的,也就是說我們索引的數據全部插入到一個shard的時候 它的聚合統計結果是準確的。
第二種:
在索引數據的時候,使用route路由字段,將所有聚合的數據分布到同一個shard即可,這樣再聚合時也是精確的。
上面的兩種辦法都是可以解決的,第一種適合數據量不大的場景下,我們直接把數據放在一份索引里面,第二種辦法適合數據量比較大的場景下,我們通過業務字段將相同屬性的數據路由在同一個shard里面即可,具體使用哪個需要和具體的業務場景相結合。
總結:
es雖然很強大,但是在一些場景下也是有局限的,比如上面提到的聚合分組的這個情況,或者聚合分組+分頁的情況,此外min,max,sum這些函數在多個shard中聚合結果是準確的,count是近似準確的,但是es能保證top 前幾的數據是精確的,這也是為什么搜索引擎一般都返回top n數據作為最終的返回結果,當然上面提到那個例子,如果聚合的key本來就很少,那么它的聚合結果也是準確的,比如按性別,月份聚合,因為這些返回的key,都是有限的,所以結果沒問題,但是一旦對分組的個數沒法確定,這種情況下出現問題的幾率就比較大,跨表或者跨分片聚合其實在任何db系統里面都會存在這種問題,所以我們應該盡量在設計業務時就考慮到這種特殊情況,然后最終做特殊處理。
轉載于:https://www.cnblogs.com/txfsheng/p/9322141.html
總結
以上是生活随笔為你收集整理的ES group分组聚合的坑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 备案交通事故怎么写?
- 下一篇: Codeforces Round #49