lucene: IO/FileNotFoundException:(Too many open files) 查询异常解决
http://stackoverflow.com/questions/6210348/too-many-open-files-error-on-lucene
今天使用lucene的IndexSearcher报这种异常,文件句柄数超多,超过了设置的65535个
问题解决后发现是IndexSearcher.close()并没有真正的关闭,看来这篇文章后知道的
看了看IndexSearcher的close方法,让我汗颜了
这样写,才是真正的关闭IndexSearcher的reader,获取reader,最后关闭
IndexSearcher.getIndexReader().close()
更彻底的IndexSearcher关闭
if (null != indexSearcher) {
try {
IndexReader indexReader = indexSearcher.getIndexReader();
indexReader.close();
indexReader = null;
indexSearcher.close();
indexSearcher = null;
} catch (IOException e) {
e.printStackTrace();
}
}
try {
IndexReader indexReader = indexSearcher.getIndexReader();
indexReader.close();
indexReader = null;
indexSearcher.close();
indexSearcher = null;
} catch (IOException e) {
e.printStackTrace();
}
}
IndexSearcherg关闭改进后,发现句柄数还是没有按照预想的使用完后就关闭的流程走,我觉得不只关闭IndexReader、IndexSearcher,看了**** - lucene使用教程4 --常用类的对象之IndexSearcher这篇文章后,可能实例化IndexReader的Directory也需要关闭,但我没试,等到了穷途末路的时候再去尝试吧
现在解决是加大文件打开句柄数,学dzh的机器,将我们的机器有原来设置的65535改为1006154
变通解决
搜索ulimit笔记,有记录设置文件打开数量的做法
原以为加大文件打开句柄数就能解决问题,但事实结果是没用,到了穷途末路的时候了,尝试关闭目录
Directory dir = FSDirectory.open(indexDirFile);
IndexReader indexReader = IndexReader.open(dir, true);
dir.close();
IndexReader indexReader = IndexReader.open(dir, true);
dir.close();
把目录关闭后,打开的索引文件句柄才是真正的关闭了,真正解决了这个问题
有这方面的问题解决,答案确实是关闭reader和directory,调用close方法
如果使用了reader的reopen方法,会返回一个新的reader,如果这个reader是最新的,跟你保存你的已实例化好的reader不同的话,建议用新reader并且把旧reader关闭,释放资源(打开文件句柄),用reopen可以提高性能,减少实例化一个新的reader需要的I/O
IndexReader.reopen(true);
reopen实战代码:
/*
* 先获取reader,如果索引文件已经变化,关闭当前indexSearcher,然后以重新获取的indexReader
* 作为参数new一个新的indexSearcher实例
*/
IndexReader indexReader=indexSearcher.getIndexReader();//获取当前的indexReader
if(!indexReader.isCurrent()){//判断是否有索引更新
// 如果有索引更新,先关闭当前的indexSearcher
indexSearcher.close();
//利用indexReader.reopen()获取新的indexReader,并作为IndexSearcher的参数创建一个新的indexSearcher
indexSearcher=new IndexSearcher(indexReader.reopen());
}
* 先获取reader,如果索引文件已经变化,关闭当前indexSearcher,然后以重新获取的indexReader
* 作为参数new一个新的indexSearcher实例
*/
IndexReader indexReader=indexSearcher.getIndexReader();//获取当前的indexReader
if(!indexReader.isCurrent()){//判断是否有索引更新
// 如果有索引更新,先关闭当前的indexSearcher
indexSearcher.close();
//利用indexReader.reopen()获取新的indexReader,并作为IndexSearcher的参数创建一个新的indexSearcher
indexSearcher=new IndexSearcher(indexReader.reopen());
}
self:
if (!indexReader.isCurrent()) {
try {
// Directory directory = indexReader.directory();
// directory.close();
// directory = null;
indexReader.close();
// indexReader = null;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
IndexReader newIndexReader = indexReader.reopen(true);
map.put("IndexReader", newIndexReader);
// if (newIndexReader != indexReader) {
// map.put("IndexReader", newIndexReader);
// } else {
// map.put("IndexReader", indexReader);
// }
}
有关reader的reopen方法详细的介绍