6

我有一个中等大小的弹性搜索索引(1.46T 或 ~1e8 文档)。它运行在 4 台服务器上,每台服务器都有 64GB Ram 在弹性和操作系统之间平均分配(用于缓存)。

我想尝试新的“重要术语”聚合,所以我启动了以下查询......

{
  "query": {
    "ids": {
      "type": "document",
      "values": [
        "xCN4T1ABZRSj6lsB3p2IMTffv9-4ztzn1R11P_NwTTc"
      ]
    }
  },
  "aggregations": {
    "Keywords": {
      "significant_terms": {
        "field": "Body"
      }
    }
  },
  "size": 0
}

它应该将指定的文档正文与索引的其余部分进行比较,并找到对文档重要但在索引中不常见的术语。

不幸的是,这总是导致

ElasticsearchException[org.elasticsearch.common.breaker.CircuitBreakingException:数据太大,数据将大于[25741911654]字节的限制];

嵌套:UncheckedExecutionException[org.elasticsearch.common.breaker.CircuitBreakingException:数据太大,数据将大于[25741911654]字节的限制];

嵌套:CircuitBreakingException[数据太大,数据将大于[25741911654]字节的限制];

一两分钟后,似乎暗示我没有足够的记忆。

有问题的弹性服务器实际上是虚拟机,所以我关闭了其他虚拟机并给每个弹性实例 96GB 和每个操作系统另外 96GB。

发生了同样的问题(不同的数字,花费的时间更长)。我手头没有可用内存超过 192GB 的硬件,所以不能再高了。

聚合不意味着对整个索引使用吗?我在查询格式方面犯了错误吗?

4

1 回答 1

5

此聚合的文档中有一条警告,关于在非常大的索引[1]的自由文本字段上使用 RAM 。在大型索引上,它适用于具有较小词汇量(例如主题标签)的较低基数字段,但许多自由文本术语和许多文档的组合是一个记忆猪。您可以查看为 Body 字段在加载 FieldData 缓存[2]时指定一个过滤器,以修剪低频术语的长尾(例如,文档频率 <2),这将减少 RAM 开销。

在此之前,我使用了该算法的一种变体,其中仅分析了最匹配的文档样本中的重要术语,并且这种方法需要更少的 RAM,因为仅从磁盘读取前 N 个文档并进行标记(使用 TermVectors 或分析器)。但是,目前 Elasticsearch 中的实现依赖于 FieldData 缓存并查找所有匹配文档的术语。

还有一件事 - 当您说要“比较指定文档的正文”时,请注意通常的操作模式是将一组文档与背景进行比较,而不仅仅是一个。所有分析均基于文档频率计数,因此对于仅包含一个文档的样本集,所有术语的前景频率都将为 1,这意味着您没有足够的证据来加强任何分析。

于 2014-04-23T22:34:57.527 回答