elasticsearch——部分聚合結果不準確

ES基于分布式,每一個搜索請求都是分發(fā)到所有的分片上單獨處理,最后匯總結果。聚合也是這樣操作。但是在這種邏輯下,會導致某些聚合的結果不準確,即實現group邏輯的terms桶

例子

curl -X GET "localhost:9200/cars/transactions/_search" -H 'Content-Type: application/json' -d'
{
    "size" : 0,
    "aggs" : { 
        "popular_colors" : { 
            "terms" : { 
              "field" : "color",
              "size": 3
            }
        }
    }
}

這里實現了一個terms聚合,以color為依據進行分組統計。結果為每種color的個數。下面是返回的結果

{
...
   "hits": {
      "hits": [] 
   },
   "aggregations": {
      "doc_count_error_upper_bound": 3,
      "sum_other_doc_count": 10,
      "popular_colors":
         "buckets": [
            {
               "key": "red", 
               "doc_count": 4 
            },
            {
               "key": "blue",
               "doc_count": 2
            },
            {
               "key": "green",
               "doc_count": 2
            }
         ]
      }
   }
}

在返回結果的aggregations中,有三個值:doc_count_error_upper_bound、sum_other_doc_count和popular_colors。這三個值表示了ES對這次聚合的評估和返回的聚合結果。

  • doc_count_error_upper_bound:表示沒有在這次聚合中返回、但是可能存在的潛在聚合結果,這里的值為 3,表除去red、blue和green之外,還可能有一個聚合結果為 3。從返回結果看,可能會排在第二名。
  • sum_other_doc_count:表示這次聚合中沒有統計到的文檔數。因為ES為分布式部署,不同文檔分散于多個分片,這樣當聚合時,會在每個分片上分別聚合,然后由協調節(jié)點匯總結果后返回。這里因為請求的是排名前三的聚合,所以每個分片只聚合了本分片中排名前三的color。其他沒有統計到的文檔數由每個節(jié)點返回后,匯總為此元素。這里值為 10,表示有10個文檔沒有參與此次聚合。
  • popular_colors:聚合結果,默認由高到低排列。key表示聚合元素的值,doc_count表示元素出現的次數。注意,這里的doc_count也是不準確的。

由此分析這一次的聚合,雖然返回了top3,但是可能存在另一個第二名,而且doc_count只是一個相對值。
本質上這種誤差是由于分布式環(huán)境中的數據隔離產生的,尤其是當獲取topK數據時,節(jié)點內的topK準確不保證整體topK準確。而且無論元素還是元素對應的doc_count,都不是準確的。
所以如果想要ES獲取準確的聚合結果,只有max、min、avg等聚合可以做到,而terms API本身不保證準確,只有通過一些額外的方法來確保或者提高準確性:

  1. 不分片,所有數據在一個shard上。這樣可以使ES在聚合中使用所有數據,為完全準確。
  2. 在聚合中使用route,將需要聚合的數據路由到同一個節(jié)點上。將這樣需要數據結構和業(yè)務邏輯的支持,一般數據很難實現。
  3. 提高聚合結果的數量。這樣可以使每一個分片節(jié)點返回更多的冗余數據,在協調節(jié)點進行數據匯總時,提高聚合結果的準確性。這種方法只保證聚合結果的近似準確,推薦使用。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容