【发布时间】:2012-07-08 11:57:51
【问题描述】:
我的问题很简单,当使用IndexReader.openIfChanged (reader)替换之前的reader,如何安全关闭oldReader?
这里是代码:(使用 Lucene 3.5)
IndexReader newReader=IndexReader.openIfChanged(reader);
if(newReader!=null){
IndexReader oldReader=reader;
IndexSearcher oldSearcher=searcher;
reader=newReader;
searcher=new IndexSearcher(newReader);
oldSearcher.close();
oldReader.close();//or oldReader.decRef(),result is the same
}
这段代码在一个守护线程中,每5秒运行一次
IndexReader instance(reader object) 是全局唯一的
由于这个变化,我得到一个例外:
org.apache.lucene.store.AlreadyClosedException: this IndexReader is closed
at org.apache.lucene.index.IndexReader.ensureOpen(IndexReader.java:297)
at org.apache.lucene.index.IndexReader.getSequentialSubReaders(IndexReader.java:1622)
at org.apache.lucene.search.TermQuery$TermWeight.scorer(TermQuery.java:98)
at org.apache.lucene.search.BooleanQuery$BooleanWeight.scorer(BooleanQuery.java:298)
at org.apache.lucene.search.BooleanQuery$BooleanWeight.scorer(BooleanQuery.java:298)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:577)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:517)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:487)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:400)
at org.zenofo.index.IndexManager.query(IndexManager.java:392)
...
IndexManager.java:392 使用reader 对象(IndexReader 实例,全局唯一)
IndexManager.query方法有大量并发请求,所有请求使用全局唯一的IndexReader实例(reader对象)
我需要关闭oldReader 只是因为:
- Too many open files in Lucene Indexing when number of users increase
- Lucene Wiki:Too many open files
参考:
我该如何解决这个问题?
【问题讨论】:
-
您确定在调用 openIfChanged 之前阅读器没有关闭吗?
-
你的并发设置是什么?如果这段代码可以同时执行,那么它可能有很多问题。无论如何,你不应该自己实现这个,因为 Lucene 已经 provides its own SearcherManager。
-
@vikas 我的问题描述了错误,我必须修改并重写问题
-
@MarkoTopolnik 感谢您的回答,
oldReader.close()包含一个守护线程,IndexReader实例是全局唯一的,IndexManager.query的方法出现异常,IndexManager.query支持并发(在我的问题之前描述错误,我已修复) -
一种简单的方法:创建一个对象,其中包含两个 final 字段,分别保存 reader 和 searcher。使用
static volatilevar 指向它。在每个索引重新打开时,创建一个新的此类对象并将其放入 var。