问题由来:
参考一些资料,以及自己知道的io操作的资源消耗,知道IndexWriter也有同样的问题,同时IndexWriter同一时间只能有一个实例存在(如果在第一个IndexWriter实例存在之后,索引目录下会产生一个write.lock文件,这个时候你想实例化第二个IndexWriter时,肯定会报错的)。所以考虑能否构造一个单例IndexWriter出来,然后一直持有。
参考了lucene API关于IndexWriter的commit方法:
Commits all pending changes (added & deleted documents, optimizations, segment merges, added indexes, etc.) to the index, and syncs all referenced index files, such that a reader will see the changes and the index updates will survive an OS or machine crash or power loss. Note that this does not wait for any running background merges to finish. This may be a costly operation, so you should test the cost in your application and do it only when really necessary.
提交所有挂起的变化到当前的索引,包括新增,删除文档,优化操作,段合并操作,添加索引等。
同时,针对当前索引的引用,比如一个IndexReader将会看到所有的当前的改变。
与此同时,针对索引的更新将会固化到存储设备上。
需要提醒的是,commit操作不会等待后台任何的合并操作完成。
commit操作有可能是一个很消耗资源的操作,所以你需要测试你的程序的消耗;如果需要可以单独进行测试。
再看lucene API关于IndexWriter的close方法:
Commits all changes to an index and closes all associated files. Note that this may be a costly operation, so, try to re-use a single writer instead of closing and opening a new one.
提交所有的针对当前索引的操作,同时关闭相关联的文件,需要注意的是这是一个很消耗资源的操作,所以应该尝试构造一个循环使用的单例的IndexWriter代替关闭和重新打开索引。
关于indexwriter实例的重用:
参考了以上文字之后,我考虑用一个单例模式在程序启动之后,始终保持当前的仅有的一个indexwriter实例,也确实实现了,但是突然间意识到一个问题:
当进程强制退出怎么办?考虑问题不周全啊!
仔细想了一下,关于重用以及资源浪费的说法是对的,但是只能作为参考,既定的程序规则还是无法打破的,当然可以打破,但是当你违背常理去做一些事情的时候,是要付出代价的。
因此关于重用的indexwriter实例,只能说是利用一个indexwriter去尽可能多的干活,但是该关闭的时候还是得关闭;而资源浪费则是时刻提醒你尽可能的减少资源浪费,仅此而已。
总结:
一般情况下索引的更新都是有时效性的:设定一个时间长度然后循环增量索引。
索引如果频繁的开关IndexWriter确实很消耗资源,另外IndexWriter只允许同一时间有一个实例存在,而针对索引的提交用commit完全就够使了,没有close IndexWriter的必要。