我正在尝试索引从tomcat服务器获取的大量日志文件。我编写了代码来打开每个文件,为每一行创建一个索引,然后使用Apache lucene存储每一行。所有这些都是使用多线程完成的。
我尝试使用此代码时出现此异常
org.apache.lucene.store.LockObtainFailedException: Lock obtain timed out:
代码
if (indexWriter.getConfig().getOpenMode() == IndexWriterConfig.OpenMode.CREATE)
{
// New index, so we just add the document (no old document can be there):
System.out.println("adding " + path);
indexWriter.addDocument(doc);
} else {
// Existing index (an old copy of this document may have been indexed) so
// we use updateDocument instead to replace the old one matching the exact
// path, if present:
System.out.println("updating " + path);
indexWriter.updateDocument(new Term("path", path), doc);
}
indexWriter.commit();
indexWriter.close();
现在我想,因为我每次提交索引,都可能导致写锁定。所以我删除了indexWriter.commit();
:
if (indexWriter.getConfig().getOpenMode() == IndexWriterConfig.OpenMode.CREATE)
{
// New index, so we just add the document (no old document can be there):
System.out.println("adding " + path);
indexWriter.addDocument(doc);
} else {
// Existing index (an old copy of this document may have been indexed) so
// we use updateDocument instead to replace the old one matching the exact
// path, if present:
System.out.println("updating " + path);
indexWriter.updateDocument(new Term("path", path), doc);
}
indexWriter.close();
现在我没有异常
问。所以我的问题是为什么indexWriter.commit();导致异常。即使我删除indexWriter.commit();我在搜索时没有遇到任何问题。那就是我得到了我想要的确切结果。那么为什么要使用indexWriter.commit();吗
答案 0 :(得分:2)
简而言之,它类似于数据库提交,除非您提交事务,添加到Solr的文档只是保存在内存中。只有在提交时才会将文档保留在索引中 如果文档在内存中时Solr崩溃,您可能会丢失这些文档。
Explanation: -
从第一天开始,Lucene的原则之一就是写一次 政策。我们从不写两次文件。通过时添加文档 IndexWriter它被索引到内存中,一旦我们达到了 我们编写的某些阈值(最大缓冲文档或RAM缓冲区大小) 从主存储器到磁盘的所有文件;你可以找到更多 在这里和这里。将文档写入磁盘会产生整个文件 新索引称为段。现在,当你索引一堆文件时 或者你在生产中运行增量索引,你可以看到 频繁更改的细分数量。但是,一旦调用commit Lucene将其整个RAM缓冲区刷新为段,同步它们 将指向属于此提交的所有段的指针写入 SEGMENTS文件。
如果文档已存在于Solr中,则只会被覆盖(由唯一ID确定) 因此,您的搜索仍然可以正常工作,但除非您提交,否则最新文档不可用于搜索。
此外,一旦打开和索引编写器,它将获得索引锁定,您应该关闭编写器以释放锁定。