【问题标题】:ElasticSearch circuit_breaking_exception (Data too large) with significant_terms aggregationElasticSearch circuit_breaking_exception(数据太大)与显着_terms 聚合
【发布时间】:2016-05-19 19:13:41
【问题描述】:

查询:

{
  "aggregations": {
    "sigTerms": {
      "significant_terms": {
        "field": "translatedTitle"
      },
      "aggs": {
        "assocs": {
          "significant_terms": {
            "field": "translatedTitle"
          }
        }
      }
    }
  },
  "size": 0,
  "from": 0,
  "query": {
    "range": {
      "timestamp": {
        "lt": "now+1d/d",
        "gte": "now/d"
      }
    }
  },
  "track_scores": false
}

错误:

{
  "bytes_limit": 6844055552,
  "bytes_wanted": 6844240272,
  "reason": "[request] Data too large, data for [<reused_arrays>] would be larger than limit of [6844055552/6.3gb]",
  "type": "circuit_breaking_exception"
}

索引大小为 5G。集群执行这个查询需要多少内存?

【问题讨论】:

  • @AndreiStefan ES 版本为 2.2.0

标签: elasticsearch significant-terms


【解决方案1】:

我不确定您要做什么,但我很想知道。既然你得到了那个例外,我可以假设那个领域的基数不小。我猜你基本上是想了解该领域中所有术语之间的关系,基于重要性。

第一个 significant_terms 聚合将考虑该字段中的所有项并确定它们的“重要程度”(计算该项在整个索引中的频率,然后将这些频率与来自range 查询文档集)。

在它这样做之后(对于所有术语),您需要第二个 significant_aggregation 来完成第一步,但现在考虑每个术语并为它做另一个 significant_aggregation。那会很痛苦基本上,您正在计算number_of_term * number_of_termssignificant_terms 计算。

最大的问题是你想做什么

如果您想查看该字段中所有术语之间的关系,由于上述原因,这将是昂贵的。我的建议是运行第一个 significant_terms 聚合,获取前 10 个左右的术语,然后使用另一个 significant_terms 聚合运行第二个查询,但可能通过父级 terms 聚合和 include only those 10 from the first query 来限制术语。

您还可以查看 sampler aggregation 并将其用作您的唯一一个重要术语聚合的父级。

另外,我不认为增加断路器限制是真正的解决方案。选择这些限制是有原因的。您可以增加它,也许它会起作用,但它必须让您问自己这是否是您的用例的正确查询(因为它听起来不像)。它在异常中的限制值可能不是最后一个...reused_arrays 指的是 Elasticsearch 中可调整大小的数组类,因此如果需要更多元素,则数组大小会增加,您可能会遇到断路器再次,换一个值。

【讨论】:

    【解决方案2】:

    您可以尝试在 elasticsearch.yml 配置文件中将 request circuit breaker 限制增加到 41%(默认为 40%)并重新启动集群:

    indices.breaker.request.limit: 41%
    

    或者,如果您不想重新启动集群,您可以使用以下方法动态更改设置:

    curl -XPUT localhost:9200/_cluster/settings -d '{
      "persistent" : {
        "indices.breaker.request.limit" : "41%" 
      }
    }'
    

    从显示的数字(即"bytes_limit": 6844055552, "bytes_wanted": 6844240272)来看,您只是缺少约 190 KB 的堆,因此增加 1% 到 41%,您应该获得 17 MB 的额外堆(您的总堆 = ~17GB ) 对于您的请求破坏者,这应该足够了。

    请确保不要将此值增加得太高,因为请求断路器还与 fielddata 断路器和其他组件共享堆,否则您将面临 OOM 的风险。

    【讨论】:

    • 嘿@esp,你能试试这个吗?
    • 这不是所需内存估计的工作方式 - bytes_wanted 不是一个准确的数字,而是一个近似值。将限制提高一小部分可能会导致相同的错误,只是bytes_limit/bytes_wanted 的值略高。
    • 这只是为了说明,当然如果他采用这种方法,他需要尝试看看什么对他有用。
    • 如果您使用的是 ElasticSearch 6.0 及更高版本,请使用此选项,并且需要身份验证curl -XPUT -H 'Content-Type: application/json' -u elastic:PASSWORD localhost:9200/_cluster/settings -d '{ "persistent" : { "indices.breaker.request.limit" : "45%" }}'
    【解决方案3】:

    断路器旨在处理请求处理需要的内存多于可用内存的情况。您可以使用以下查询设置限制

    PUT /_cluster/settings
    {
      "persistent" : {
        "indices.breaker.request.limit" : "45%" 
      }
    }
    

    您可以获取更多信息

    https://www.elastic.co/guide/en/elasticsearch/reference/current/circuit-breaker.html https://www.elastic.co/guide/en/elasticsearch/reference/1.4/index-modules-fielddata.html

    【讨论】:

      猜你喜欢
      • 2020-09-04
      • 1970-01-01
      • 1970-01-01
      • 2020-11-28
      • 1970-01-01
      • 1970-01-01
      • 2020-12-15
      • 2021-03-01
      • 1970-01-01
      相关资源
      最近更新 更多