Python 如何解决大规模Lucene索引写入中的MergeException?

Python 如何解决大规模Lucene索引写入中的MergeException?,python,multithreading,merge,lucene,indexing,Python,Multithreading,Merge,Lucene,Indexing,我有一个python脚本,可以简单地将unicode语句索引到lucene索引中。在100个句子和我的1000个句子的审判中效果很好。然而,当我需要索引200000个句子时,我在4514个句子中得到了一个合并错误,问题是什么,如何解决 错误: Exception in thread "Thread-4543" org.apache.lucene.index.MergePolicy$MergeException: java.io.FileNotFoundException: /home/alvas

我有一个python脚本,可以简单地将unicode语句索引到lucene索引中。在100个句子和我的1000个句子的审判中效果很好。然而,当我需要索引200000个句子时,我在4514个句子中得到了一个合并错误,问题是什么,如何解决

错误

Exception in thread "Thread-4543" org.apache.lucene.index.MergePolicy$MergeException: java.io.FileNotFoundException: /home/alvas/europarl/index/_70g.tii (Too many open files)
    at org.apache.lucene.index.ConcurrentMergeScheduler$MergeThread.run(ConcurrentMergeScheduler.java:271)
Traceback (most recent call last):
Caused by: java.io.FileNotFoundException: /home/alvas/europarl/index/_70g.tii (Too many open files)
    at java.io.RandomAccessFile.open(Native Method)  File "indexer.py", line 183, in <module>

    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:216)
    at org.apache.lucene.store.FSDirectory$FSIndexOutput.<init>(FSDirectory.java:593)
    at org.apache.lucene.store.FSDirectory.createOutput(FSDirectory.java:435)
    at org.apache.lucene.index.TermInfosWriter.initialize(TermInfosWriter.java:91)
    at org.apache.lucene.index.TermInfosWriter.<init>(TermInfosWriter.java:83)
        at org.apache.lucene.index.TermInfosWriter.<init>(TermInfosWriter.java:77)
incrementalIndexing(sfile,tfile,indexDir)
    at org.apache.lucene.index.SegmentMerger.mergeTerms(SegmentMerger.java:381)
    at org.apache.lucene.index.SegmentMerger.merge(SegmentMerger.java:134)  File "indexer.py", line 141, in incrementalIndexing

    at org.apache.lucene.index.IndexWriter.mergeMiddle(IndexWriter.java:3109)
    at org.apache.lucene.index.IndexWriter.merge(IndexWriter.java:2834)
    at org.apache.lucene.index.ConcurrentMergeScheduler$MergeThread.run(ConcurrentMergeScheduler.java:240)
    writer.optimize(); writer.close()
lucene.JavaError: java.io.IOException: background merge hit exception: _70e:c4513 _70f:c1 into _70g [optimize]
    Java stacktrace:
java.io.IOException: background merge hit exception: _70e:c4513 _70f:c1 into _70g [optimize]
    at org.apache.lucene.index.IndexWriter.optimize(IndexWriter.java:1749)
    at org.apache.lucene.index.IndexWriter.optimize(IndexWriter.java:1689)
    at org.apache.lucene.index.IndexWriter.optimize(IndexWriter.java:1669)
Caused by: java.io.FileNotFoundException: /home/alvas/europarl/index/_70g.tii (Too many open files)
    at java.io.RandomAccessFile.open(Native Method)
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:216)
    at org.apache.lucene.store.FSDirectory$FSIndexOutput.<init>(FSDirectory.java:593)
    at org.apache.lucene.store.FSDirectory.createOutput(FSDirectory.java:435)
    at org.apache.lucene.index.TermInfosWriter.initialize(TermInfosWriter.java:91)
    at org.apache.lucene.index.TermInfosWriter.<init>(TermInfosWriter.java:83)
    at org.apache.lucene.index.TermInfosWriter.<init>(TermInfosWriter.java:77)
    at org.apache.lucene.index.SegmentMerger.mergeTerms(SegmentMerger.java:381)
    at org.apache.lucene.index.SegmentMerger.merge(SegmentMerger.java:134)
    at org.apache.lucene.index.IndexWriter.mergeMiddle(IndexWriter.java:3109)
    at org.apache.lucene.index.IndexWriter.merge(IndexWriter.java:2834)
    at org.apache.lucene.index.ConcurrentMergeScheduler$MergeThread.run(ConcurrentMergeScheduler.java:240)
线程“thread-4543”org.apache.lucene.index.MergePolicy$MergeException:java.io.FileNotFoundException:/home/alvas/europarl/index/_70g.tii中的异常(打开的文件太多) 位于org.apache.lucene.index.ConcurrentMergeScheduler$mergesThread.run(ConcurrentMergeScheduler.java:271) 回溯(最近一次呼叫最后一次): 原因:java.io.FileNotFoundException:/home/alvas/europarl/index/_70g.tii(打开的文件太多) 在java.io.RandomAccessFile.open(本机方法)文件“indexer.py”中的第183行 位于java.io.RandomAccessFile。(RandomAccessFile.java:216) 在org.apache.lucene.store.FSDirectory$FSIndexOutput.(FSDirectory.java:593) 位于org.apache.lucene.store.FSDirectory.createOutput(FSDirectory.java:435) 位于org.apache.lucene.index.TermInfosWriter.initialize(TermInfosWriter.java:91) 位于org.apache.lucene.index.TermInfosWriter(TermInfosWriter.java:83) 位于org.apache.lucene.index.TermInfosWriter.(TermInfosWriter.java:77) 增量索引(sfile、tfile、indexDir) 位于org.apache.lucene.index.SegmentMerge.mergeTerms(segmentMerge.java:381) 在org.apache.lucene.index.segmentmerge.merge(segmentmerge.java:134)文件“indexer.py”中的增量索引第141行 位于org.apache.lucene.index.IndexWriter.mergeMiddle(IndexWriter.java:3109) 位于org.apache.lucene.index.IndexWriter.merge(IndexWriter.java:2834) 位于org.apache.lucene.index.ConcurrentMergeScheduler$mergerthread.run(ConcurrentMergeScheduler.java:240) writer.optimize();writer.close() lucene.JavaError:java.io.IOException:后台合并命中异常:_70e:c4513 _70f:c1到_70g[优化] Java stacktrace: java.io.IOException:后台合并命中异常:_70e:c4513 _70f:c1到_70g[优化] 位于org.apache.lucene.index.IndexWriter.optimize(IndexWriter.java:1749) 位于org.apache.lucene.index.IndexWriter.optimize(IndexWriter.java:1689) 位于org.apache.lucene.index.IndexWriter.optimize(IndexWriter.java:1669) 原因:java.io.FileNotFoundException:/home/alvas/europarl/index/_70g.tii(打开的文件太多) 位于java.io.RandomAccessFile.open(本机方法) 位于java.io.RandomAccessFile。(RandomAccessFile.java:216) 在org.apache.lucene.store.FSDirectory$FSIndexOutput.(FSDirectory.java:593) 位于org.apache.lucene.store.FSDirectory.createOutput(FSDirectory.java:435) 位于org.apache.lucene.index.TermInfosWriter.initialize(TermInfosWriter.java:91) 位于org.apache.lucene.index.TermInfosWriter(TermInfosWriter.java:83) 位于org.apache.lucene.index.TermInfosWriter.(TermInfosWriter.java:77) 位于org.apache.lucene.index.SegmentMerge.mergeTerms(segmentMerge.java:381) 位于org.apache.lucene.index.segmentmerge.merge(segmentmerge.java:134) 位于org.apache.lucene.index.IndexWriter.mergeMiddle(IndexWriter.java:3109) 位于org.apache.lucene.index.IndexWriter.merge(IndexWriter.java:2834) 位于org.apache.lucene.index.ConcurrentMergeScheduler$mergerthread.run(ConcurrentMergeScheduler.java:240) 我的代码:

示例输入文件:

您有来自Java的“打开的文件太多”错误。尝试分批添加文档,然后在每批(比如)1000个文档之后提交并优化。存在其他解决方案,但与搜索后端相关,而不是与Python脚本相关。

您有来自Java的“打开的文件太多”错误。尝试分批添加文档,然后在每批(比如)1000个文档之后提交并优化。存在其他解决方案,但与搜索后端相关,而不是与Python脚本相关。

您在第169行重新分配了
filedir
,而没有关闭在第116行创建的解决方案。我认为这是一个错误,因为你不需要创建新的,你可以重用旧的。另外,你会在每一个循环中创建它,它只会泄漏句柄,因为它们永远不会关闭

如果使用其他一些方法,您可以创建一个新的
filedir
,而不关闭它,
createEmptyIndex
中的第106行和
deleteFromIndex
中的第97行

retrieveUniqID
中还有另一个不太明显的问题。您正在创建
searcher
,但只有在第87行的条件
if cont==content:
为真时才关闭它。如果没有匹配项,而您在第91行
返回None
,则永远不会关闭该搜索程序。在本例中,由于您将字符串传递给
索引搜索器
构造函数,因此它在内部创建了一个
目录
,在某些情况下不会关闭该目录。如果愿意,可以使用try/finally块确保始终关闭它

上述所有调用都是从
增量索引中的主循环发出的,因此泄漏句柄的数量会迅速增加

另外,需要考虑的是:所有这些类,
indexsearch
IndexReader
IndexWriter
目录
都是线程安全的,每次创建新类的成本都很高。您最好进行一次小的重新设计,以尽量减少打开和关闭它们所需的时间。它实际上可能只是您的代码,因为您可以传递已经创建的实例,这将清除不同方法中大量的初始化混乱

由于您似乎也希望能够立即访问已编制索引的文档,因此我将研究通过
IndexWriter.GetReader()
方法获取
IndexReader
(以及您的IndexSearcher),或者通过刷新读卡器,如:
reader=reader.Refresh()