我目前正在开发基于spring mvc的并发应用程序,它正在为特定类型的请求创建lucene索引。我之前试图通过每个线程立即提交每个文档,但由于在重度并发负载下等待获取写锁定,线程开始挂起。
java.lang.Thread.State:BLOCKED(在对象监视器上)at org.apache.lucene.index.IndexWriter.commitInternal(IndexWriter.java:2953) - 等待锁定< 0x0000000783bd7820> (java.lang.Object)org.apache.lucene.index.IndexWriter.commit(IndexWriter.java:2930)
现在我正在尝试将几个文档放在一起。我知道我可以通过使用一些计时器之王定期提交。 但我正在搜索是否有办法收集批量并在高并发负载下将它们一起提交并在低并发负载下立即提交。
我试图维护一个原子计数器变量来检查addDocument
代码块中有多少个线程,以及在所有线程完成添加文档之后是否有多个线程提交。
class NRTIndexManager {
//initialization of index writer
private AtomicInteger threadsInWritingBlock = new AtomicInteger();
private AtomicInteger pendingCommits = new AtomicInteger();
@Override
public void addNewDirectory(String id, String content) {
try {
threadsInWritingBlock.incrementAndGet();
indexWriter.addDocument(createDocument(id, content));
if (threadsInWritingBlock.decrementAndGet() == 0 || pendingCommits.incrementAndGet() > PENDING_COMMIT_THRESHOLD) {
pendingCommits.set(0);
indexWriter.commit();
}
} catch (IOException e) {
LOGGER.error("Unexpected error occurred. ", e);
}
}
}
但它没有给我成功的结果,因为addDocument
方法在与commit
方法比较时没有花费太多时间来执行。
如果你能引导我找到一些基于lucene的机制,算法或任何其他想法来实现这一目标,我将非常感激。