【问题标题】:Elasticsearch does not respond with huge dataElasticsearch 不响应海量数据
【发布时间】:2014-05-24 20:39:46
【问题描述】:

我正在使用 centos5 并使用 1.0.0 版本运行带有 -Xms808m -Xmx808m -Xss256k 参数的 elasticsearch。有 17 个索引,总共 30200583 个文档。每个索引的文档计数在 1000000 到 2000000 之间。我创建请求查询,例如(每个索引都有日期字段);

{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "date": {
              "to": "2014-06-01 14:14:00",
              "from": "2014-04-01 00:00:00"
            }
          }
        }
      ],
      "should": [],
      "must_not": [],
      "minimum_number_should_match": 1
    }
  },
  "from": 0,
  "size": "50"
}

它给出响应;

{
   took: 5903
   timed_out: false
   _shards: {
      total: 17
      successful: 17
      failed: 0
   },
   hits: {
   total: 30200583
...
...
...}

但是,当我在 elasticsearch-head 工具上发送最后 50 行的查询时,例如;

{
  ...
  ...
  ...
  "from": 30200533,
  "size": "50"
}

它没有给出响应并抛出异常;

ava.lang.OutOfMemoryError: Java heap space
        at org.apache.lucene.store.DataOutput.copyBytes(DataOutput.java:247)
        at org.apache.lucene.store.Directory.copy(Directory.java:186)
        at org.elasticsearch.index.store.Store$StoreDirectory.copy(Store.java:348)
        at org.apache.lucene.store.TrackingDirectoryWrapper.copy(TrackingDirectoryWrapper.java:50)
        at org.apache.lucene.index.IndexWriter.createCompoundFile(IndexWriter.java:4596)
        at org.apache.lucene.index.DocumentsWriterPerThread.sealFlushedSegment(DocumentsWriterPerThread.java:535)
        at org.apache.lucene.index.DocumentsWriterPerThread.flush(DocumentsWriterPerThread.java:502)
        at org.apache.lucene.index.DocumentsWriter.doFlush(DocumentsWriter.java:506)
        at org.apache.lucene.index.DocumentsWriter.flushAllThreads(DocumentsWriter.java:616)
        at org.apache.lucene.index.IndexWriter.getReader(IndexWriter.java:370)
        at org.apache.lucene.index.StandardDirectoryReader.doOpenFromWriter(StandardDirectoryReader.java:285)
        at org.apache.lucene.index.StandardDirectoryReader.doOpenIfChanged(StandardDirectoryReader.java:260)
        at org.apache.lucene.index.StandardDirectoryReader.doOpenIfChanged(StandardDirectoryReader.java:250)
        at org.apache.lucene.index.DirectoryReader.openIfChanged(DirectoryReader.java:170)
        at org.apache.lucene.search.XSearcherManager.refreshIfNeeded(XSearcherManager.java:123)
        at org.apache.lucene.search.XSearcherManager.refreshIfNeeded(XSearcherManager.java:59)
        at org.apache.lucene.search.XReferenceManager.doMaybeRefresh(XReferenceManager.java:180)
        at org.apache.lucene.search.XReferenceManager.maybeRefresh(XReferenceManager.java:229)
        at org.elasticsearch.index.engine.internal.InternalEngine.refresh(InternalEngine.java:730)
        at org.elasticsearch.index.shard.service.InternalIndexShard.refresh(InternalIndexShard.java:477)
        at org.elasticsearch.index.shard.service.InternalIndexShard$EngineRefresher$1.run(InternalIndexShard.java:924)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:619)

有什么问题?是 java 堆空间不足还是我的查询导致了这个堆空间错误?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    这两个问题的答案都是“是”。您没有足够的堆空间,这就是您看到错误的原因,而查询导致错误是因为您没有足够的堆空间。

    原因是因为排序,深度分页非常昂贵。要检索第 20 个元素,您需要将元素 1-20 保留在内存中并排序。要检索第 1,000,000 个元素,您需要将第 1-999,999 个元素保留在内存中并进行排序。

    这通常需要大量内存。

    有几个选项:

    • 获取更多内存。问题解决了
    • 使用scan/scroll 而不是普通搜索。扫描/滚动不执行评分,因此不需要维护排序顺序,这使得它非常节省内存
    • 使用不同的排序标准(例如反向排序)或更小的窗口(例如更小的日期范围,以便您可以翻页)

    【讨论】:

      猜你喜欢
      • 2021-02-10
      • 1970-01-01
      • 1970-01-01
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 2018-12-10
      • 1970-01-01
      相关资源
      最近更新 更多