Python 如何解决大规模Lucene索引写入中的MergeException?
我有一个python脚本,可以简单地将unicode语句索引到lucene索引中。在100个句子和我的1000个句子的审判中效果很好。然而,当我需要索引200000个句子时,我在4514个句子中得到了一个合并错误,问题是什么,如何解决 错误: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
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()