ES Terms聚合统计不准确问题

当数据分布与多个 shard 上的时候,Coordinating Node 无法看到数据的全貌,从而会导致聚合的数据不准确。

如下图所示,需要统计 node1 和 node2 中的 Top3,本应返回的是a(10) b(6) c(6),但是实际返回结果并不如此。

解决办法

第一种办法,将 Shard 数设置成 1,可以消除数据分散的问题。但是也会带来无法承载大数据量的缺点。

第二种办法,合理地设置 Shard_Size 大小,也就是说每次从 Shard 上额外获取一些数据,来提升准确度。

{
  "size": 0,
  "aggs": {
    "users": {
      "terms": {
        "field": "age",
        "size": 1,
        "shard_size": 10
      }
    }
  }
}

shard_size 的大小多少才算是合理呢?

在 terms 聚合返回结果中有如下两个统计值:

1、doc_count_error_upper_bond,表示被遗漏的 term 可能最大值。

2、sum_other_doc_count,返回结果 bucket 的 term 外其他 term 的文档总数。

还是最上面图片中示例,它返回的这两个指标为如下结果

{
  "doc_count_error_upper_bond": 6,
  "sum_other_doc_count": 6
}

这是怎么算出来的呢?首先doc_count_error_upper_bond这个指标,它表示被遗漏的 term 可能的最大值,那么第一个 node,它返回的最小值是 4,对它来说,未返回可能的最大值为 4,也就是 node1 已返回中的最小值,同理,对于第二个 node,它可能未返回的最大值为 2,此时4+2等于6sum_other_doc_count为返回结果之外的文档总数,从图中可以看到,第一个 node 未返回的是 c,它有 3 个文档,第二个 node 未返回的也是 c,也有 3 个文档,3+3 等于 6。也可以用文档总数减去已返回的文档总数,之后的值就是sum_other_doc_count的结果。

通过设定show_term_doc_count_error可以查看每个 bucket 的误差最大值。

{
  "size": 0,
  "aggs": {
    "users": {
      "terms": {
        "field": "age",
        "size": 1,
        "show_term_doc_count_error": true
      }
    }
  }
}

在返回中会多一个doc_count_error_upper_bond字段,当它等于0的时候,表示计算是准确的。所以,可以调整shard_size的大小来保证doc_count_error_upper_bond等于0,就保证了统计的准确性。缺点是增加了整体的计算量,降低了响应时间。

如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注