4

我有一个工作中的 Lucene 4.3.1 集群,我正在添加一个自动热备份过程,类似于 Manning 的“Lucene in Action”一书中描述的内容,以及那里的几篇博客文章。不过本书是基于Lucene 2.3的,API在4.3.1略有改动。这本书说要实例化IndexWriter这样的:

IndexDeletionPolicy policy = new KeepOnlyLastCommitDeletionPolicy();
SnapshotDeletionPolicy snapshotter = new SnapshotDeletionPolicy(policy);
IndexWriter writer = new IndexWriter(dir, analyzer, snapshotter,
                                 IndexWriter.MaxFieldLength.UNLIMITED);

在进行备份时:

try {
   IndexCommit commit = snapshotter.snapshot();
   Collection<String> fileNames = commit.getFileNames();
   /*<iterate over & copy files from fileNames>*/
} finally {
   snapshotter.release();
}

然而,Lucene 4.x 似乎在某些时候改变了这种情况。SnapshotDeletionPolicy 现在使用 IndexWriterConfig 进行配置,并且在创建 IndexWriter 时传入。这是我到目前为止的代码:

public Indexer(Directory indexDir, PrintStream printStream) throws IOException {
    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_43, new Analyzer());
    snapshotter = new SnapshotDeletionPolicy(new KeepOnlyLastCommitDeletionPolicy());
    writerConfig.setIndexDeletionPolicy(snapshotter);
    indexWriter = new IndexWriter(indexDir, writerConfig);
}

而且在开始备份时,您不能只做snapshotter.snapshot(). 您现在必须指定一个任意commitIdentifierid,并在完成释放快照后使用它。

SnapshotDeletionPolicy snapshotter = indexer.getSnapshotter();
String commitIdentifier = generateCommitIdentifier();
try {
    IndexCommit commit = snapshotter.snapshot(commitIdentifier);
    for (String fileName : commit.getFileNames()) {
        backupFile(fileName);
    }
} catch (Exception e) {
    logger.error("Exception", e);
} finally {
    snapshotter.release(commitIdentifier);
    indexer.deleteUnusedFiles();
}

但是,这似乎不起作用。无论是否有文档被索引,也无论我是否承诺,我的调用snapshotter.snapshot(commitIdentifier)总是会抛出一个IllegalStateException说法No index commit to snapshot。查看代码,SnapshotDeletionPolicy 似乎认为没有提交,即使我每 5 秒左右提交一次磁盘。我已经验证过,并且一直在编写文档并将其提交给索引,但snapshotter始终认为提交的次数为零。

谁能告诉我我可能做错了什么?让我知道是否需要发布更多详细信息。

4

1 回答 1

4

我将同样的问题发布到 Lucene java-user 邮件列表,并且几乎立即得到了答案。问题是您最初用于配置的 SnapshotDeletionPolicyIndexWriter与 IndexWriter 使用的不同。在构造时,IndexWriter实际上克隆了SnapshotDeletionPolicy您传入的内容,因此上面的第一个代码块应如下所示:

public Indexer(Directory indexDir, PrintStream printStream) throws IOException {
    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_43, new Analyzer());
    writerConfig.setIndexDeletionPolicy(new SnapshotDeletionPolicy(new KeepOnlyLastCommitDeletionPolicy()));
    indexWriter = new IndexWriter(indexDir, writerConfig);
    snapshotter = (SnapshotDeletionPolicy) indexWriter.getConfig().getIndexDeletionPolicy();
} 

请注意最后一行,您将在其中将快照程序设置为IndexDeletionPolicyIndexWriter 配置中的。那是关键。之后,原始问题中详述的第二块代码完美运行。

作为参考,这是我从 Apache Lucene 邮件列表中得到的答案。

于 2013-07-31T21:09:03.003 回答