1

大規模な Lucene インデックスを作成しています。挿入する各ドキュメントは、挿入する前に少し「まとめる」必要があります。データベースからすべてのドキュメントを読み取り、それらをインデックスに挿入しています。Lucene を使用すると、いくつかの異なるインデックスを作成し、後でそれらをマージできるため、次のように考えました。

// we'll use a producer/consumer pattern for the job
var documents = new BlockingCollection<Document>();

// we'll have a pool of index writers (each will create its own index)
var indexWriters = new ConcurrentBag<IndexWriter>();

// start filling the collection with documents
Task writerTask = new Task(() => {
    foreach(document in database)
        documents.Add(document);
    domains.CompleteAdding();
}, TaskCreationOptions.LongRunning);
writerTask.Start();

// iterate through the collection, obtaining index writers from the pool and
// creating them when necessary.
Parallel.ForEach(documents.GetConsumingEnumerable(token.Token), document =>
{
    IndexWriter writer;
    if(!indexWriters.TryTake(out writer))
    {
        var dirInfo = new DirectoryInfo(string.Concat(_indexPath, "\\~", Guid.NewGuid().ToString("N")));
        dirInfo.Create();
        var dir = FSDirectory.Open(dirInfo);
        var indexWriter = new IndexWriter(dir, getAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED);
    }
    // prepare and insert the document into the current index
    WriteDocument(writer, document);
    indexWriters.Add(writer); // put the writer back in the pool
});

// now get all of the writers and merge the indexes together...

私が一時停止した唯一の懸念は、最初から最適な数のスレッドを作成するよりも、反復ごとにプールから IndexWriter をプルする (そして最後に戻す) ほうが効率が悪い可能性があることでした。 ConcurrentBag は非常に効率的で、処理のオーバーヘッドが非常に低くなります。

私の解決策は大丈夫ですか?それとも、より良い解決策を求めて叫びますか?

アップデート:

いくつかのテストの後、データベースからの読み込みは、実際のインデックス作成よりも少し遅いと思います。また、1 つのスレッドしか使用できず、16 のインデックスと約 170 万のドキュメントをマージしていたため、最終的なインデックスのマージも遅くなります。それでも、私は元の質問についての考えを受け入れています。

4

1 に答える 1

1

私が見た問題Parallel.ForEachの1つは、CPU使用率が低いときに、コアごとに通常のスレッドを超えてスレッドを追加することを決定できることです。これは、リモートサーバーの応答を待機しているタスクには意味がありますが、ディスクを大量に消費するプロセスの場合、ディスクがスラッシングしているため、パフォーマンスが低下することがあります。

処理がディスクバウンドでCPUバウンドではない場合は、を追加してParallelOptionsに設定し、ディスクが不必要にスラッシングされないようにすることMaxDegreeOfParallelismをお勧めします。Parallel.ForEach

于 2010-08-25T03:38:38.127 に答える