【问题标题】:Solr - Java out of memorySolr - Java 内存不足
【发布时间】:2012-12-12 09:23:09
【问题描述】:

我有一个应用程序可以创建一个相当大的 Solr 3.6 索引,大约300GB 1B 文档,每天分为 10 个核心。索引效果很好,我使用循环算法在核心之间均匀分布文档。搜索对我来说也很有效,直到返回结果集大于 100K+ 文档。

此时,我返回了一个 java 错误:OutOfMemoryError 或 SolrException:解析错误

我的搜索很简单,不使用通配符或排序或分面搜索,但它似乎在返回之前缓冲了整个结果集。我服务器上的物理内存是 256G,我运行的是 Solaris 10。我使用的是 32 位的默认 java,但也尝试过 32 位和 64 位的 java 7。

当我使用 64 位 java 时,我可以使用 –Xmx 选项将最大内存增加到足以返回 1M+ 文档,但它实际上只需要一个 Solr 进程所需的所有内存。

除了用数百个小索引重新设计我的应用程序之外,是否有人对如何在没有大量 RAM 的情况下从 Solr 获取大型搜索结果集有任何建议?

【问题讨论】:

  • 您的文件有多大?你在索引什么,你在存储什么? “分成10个核心”是什么意思?
  • 使用 32 位 jvm,您将被限制在大约 3gig 的堆中,所以如果这确实需要更多,那么您绝对需要 64 位,但这似乎基于您的让事情运行的能力,尽管几乎放弃了整个机器的 RAM。有关如何深入进行内存分配分析的一些建议,请参阅此问题:stackoverflow.com/questions/1839599/…
  • 我认为这是 32 位 JVM 的 2GB 限制:stackoverflow.com/questions/2457514/…
  • 我正在索引发票类型的文档,这些文档通常每个不到 1k。当我说分裂时,我指的是多核。我为每个 Solr 进程配置了 10 个内核。每天有1个Solr进程,让我可以进一步划分搜索和索引的处理,也可以轻松老化索引。
  • 为什么 Solr 需要在返回之前缓冲我的查询结果?我没有进行任何排序或分面搜索。我可以理解使用缓冲读取器从磁盘读取,但它不应该要求它缓冲整个结果集,不是吗?

标签: java solr lucene


【解决方案1】:

您可以尝试禁用各种caches(例如filterCachequeryResultCachedocumentCache)。这可能会损害性能,但可能会给您一些喘息的空间。

如果您的 Solr HTTP/XML 响应很大,您可以考虑 placing Solr under the same JVM 甚至使用原始 Lucene 来节省 XML 开销。

除此之外,恐怕您还需要研究分片。

【讨论】:

  • 我会考虑调整或关闭这些缓存参数,并让您知道在我的情况下它是否/多少提高了内存利用率。谢谢。
  • 我已经测试了关闭您建议的每个缓存参数,包括来自 SolrCaching wiki 的一些附加参数,但不幸的是结果并不好。正如我使用 prstat 观察到的,没有任何参数影响内存利用率。正如您所预测的,一些参数确实对性能产生了负面影响。您是否了解为什么 Solr 会在写入输出之前缓冲整个结果,即使在简单的搜索场景中也是如此?
  • 我更喜欢 Lucene 而不是 Solr,所以我不太了解 Solr 内部结构。然而,在 Lucene 世界中,搜索结果只需要非常有限的 RAM:array of rather inexpensive objects。我猜 Solr 可能会遍历所有结果集并加载每个文档。相反,您可以一个一个地加载文档并让 GC 完成它的工作。您可以尝试使用Luke 运行索引:只需执行相同的搜索,看看使用了多少内存。
  • 谢谢。我来看看卢克。如果您知道在不缓冲结果的情况下使用 Lucene 进行搜索的任何好的代码示例,请提供。我将尝试使用 Lucene 自行开发,而不是进一步分片我的应用程序。
  • 我强烈推荐Lucene in Action,它包含所有示例等等。由 Lucene/Solr 的作者编写。
猜你喜欢
  • 2012-05-04
  • 2012-03-31
  • 1970-01-01
  • 2013-10-23
  • 2012-06-21
  • 2013-09-10
  • 2017-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多