機械学習プロジェクトで、3 GB サイズのインデックスで 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);
}
}