我需要在我的机器学习项目中以 3GB 大小的索引执行 >3000 个查询。
为了提高性能,我创建了 4 个线程(我在我的 macbook pro 中有 4 个内核)并且我给了每个线程总查询的一部分(如果我总共有 N 个查询,那么每个线程有 n/4 个查询)。
我通过打开我的索引FSDirectory.open(file)
,然后将其分享IndexSearcher
给所有线程。
问题是我没有看到任何性能改进,也没有 cpu 增加。我玩了不同数量的线程,但仍然没有变化。
将整个索引保存在 RAM 中是不可能的!
我在其他线程上看到一个解决方案是以只读方式打开索引,但我使用 lucene 4.3,其中从读取器中删除了写入选项,因此不再担心只读模式!
我知道此页面以及提供但看起来过时的提示。
所以我的问题是如何并行索引搜索以提高 lucene 的实际性能?
下面是我正在使用的示例代码:
List<String> queryList = new ArrayList<String>();
List<Thread> threads = new ArrayList<Thread>();
for(int i=0;i<NUMBER_THREADS;i++){
List<String> querySubList = queryList.subList(fromIndex, toIndex);
QueryParser ngramIndexQueryParser = new QueryParser(Version.LUCENE_43, "ngram", new KeywordAnalyzer());
startWorker(querySubList, threads, date, ngramIndexQueryParser, nGramSearcher);
}
public static void startWorker(List<String> querySubList, List<Thread> threads,QueryParser ngramIndexQueryParser,IndexSearcher nGramSearcher){
NGramIndexSearch task = new NGramIndexSearch(queryList, ngramIndexQueryParser, nGramSearcher);
Thread worker = new Thread(task);
worker.start();
threads.add(worker);
}
public class NGramIndexSearch implements Runnable {
public NGramIndexSearch(List<String> queryList, String year,QueryParser queryParser, IndexSearcher searcher){
//initialization
}
public void run() {
for(String q:queryList){
Query query = queryParser.parse(queryText);
TopDocs topDocs = searcher.search(query, nrOfDocsToReturn);
}
}