Solr numDocs溢出

时间:2012-01-20 09:03:40

标签: solr lucene

我们正在运行Solr来索引大量数据,然后遇到了一个非常有趣的问题,我无法在任何地方找到任何帮助。

似乎Solr使用带符号的32位整数来计算当前索引中的文档数。我们刚刚达到该数字,我们的Solr统计页面显示以下内容:

numDocs : -2116382092
maxDoc : -2114669444 

Solr似乎仍然能够很好地索引传入数据,但是当我们搜索时,我们得到一个NegativeArraySizeException(参见下面的stacktrace)

我们假设错误和溢出是连接的(我相信这是一个公平的假设)。 Solr文档中没有任何内容,到目前为止,我还未能找到有关该主题的任何相关帮助。该问题的解决方案最有可能放弃索引的一大块以减小MAX_INT以下的大小,但我们不确定这是否有效,因为Solr很可能必须执行搜索才能找到要删除的文档。 / p>

我想这不是一个问题,因为它说的是事实,但我想知道是否有其他人遇到过这个问题,如果有的话,你是如何解决的? < / p>

 java.lang.NegativeArraySizeException
    at org.apache.solr.search.DocSetCollector.<init>(DocSetHitCollector.java:47)
    at org.apache.solr.search.SolrIndexSearcher.getDocSetNC(SolrIndexSearcher.java:627)
    at org.apache.solr.search.SolrIndexSearcher.getPositiveDocSet(SolrIndexSearcher.java:563)
    at org.apache.solr.search.SolrIndexSearcher.getDocSet(SolrIndexSearcher.java:592)
    at org.apache.solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:903)
    at org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:884)
    at org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:341)
    at org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:182)
    at org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:195)
    at    org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:131)
    at org.apache.solr.core.SolrCore.execute(SolrCore.java:1316)
    at org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:338)
    at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
    at     org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
    at     org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:662)

2 个答案:

答案 0 :(得分:2)

我们在经历了一些痛苦之后设法解决了这个问题。

我们做了什么以及我们如何解决它

首先我们运行CheckIndex以验证所有段和它自己的索引状态良好并且没有损坏。这也让我们知道我们有足够的RAM来在以后的较大段上做一些真正的工作。正如所料,CheckIndex的结果还可以。 CheckIndex 在Lucene库中可用。

第二步是将索引分成两部分(不是一半)。 在我们的例子中,我们有一个由大约17亿个文档组成的巨大段,我们只是从源索引中分离出该段并创建了两个新索引,一个是大段,另一个是我们剩下的20个段。 为此,我们使用了 IndexSplitter ,也来自Lucene库。

拆分索引需要Lucene 3.0.x,我们只安装了Lucene 2.9.3(与Solr 1.4.1捆绑在一起)。我们下载了一个单独的Lucene 3.0.3实例来获取IndexSplitter。 创建的两个新索引与我们的Lucene版本不兼容,因此我们最终必须在我们的Solr安装中将Lucene升级到2.9.4,它可以读取3.0.x索引。

然后我们引导Solr指向每个新索引,一次一个。这次numDocs低于MAX_INT,我们可以运行我们的删除语句。 在对两个新索引执行此操作之后,我们只需使用 IndexMerge 工具将它们合并在一起,同样在Lucene库中,剩下的内容最终得到一个健康的15亿个doc索引,它将为我们提供另一对几个月:) 这里学到的经验是在我们达到上限之前运行删除查询。

向所有Lucene专家提问:

在MAX_INT被击中后继续索引时会发生什么?我们覆盖数据吗?如果是,最有可能覆盖哪些数据?

答案 1 :(得分:1)

您是否尝试过使用分布式搜索?

“如果您有太多文档,由于RAM或索引大小的原因,您根本无法将它们全部放在一个盒子上,您可以将索引拆分为多个部分,称为分片。” Lucidworks