2010-10-08 15 views
0

Je voudrais accélérer l'indexation de 10 Go de données dans un index Lucene. Le TPL serait-il un bon moyen de le faire? Aurais-je besoin de diviser les données en morceaux et de faire en sorte que chaque thread commence à indexer des morceaux?Indexation de Lucene avec des extensions parallèles

Pour que l'interface utilisateur reste réactive, BackgroundWorker serait-il la meilleure approche, ou tâche, ou quelque chose d'autre?

Est-ce que SOLR fait déjà quelque chose comme ça? Ou serait-il toujours utile de coder cela moi-même.

Répondre

1

Si vous voulez plusieurs threads d'écrire à un seul IndexWriter alors je voudrais juste frayer un fil qui fait quelque chose comme

Parallel.ForEach(docs, d => { writer.Add(d,analyzer) }); 

Alors que les accords .NET avec partage les données.

Avec des tailles d'index de grande taille, certaines personnes trouvent des améliorations de performances en ayant plusieurs index dans lesquels ils écrivent, puis fusionnent tous les index ensemble. Ma compréhension est que cela n'est vraiment utile que pour les index vraiment massifs, mais si vous voulez faire cela, alors vous aurez probablement besoin de faire le découpage des données vous-même. Dans ce cas, l'utilisation d'une bibliothèque plus complète comme tpl peut être utile. Solr est intrinsèquement multithread, donc vous feriez exactement le même extrait que je vous ai donné auparavant, sauf qu'au lieu d'appeler directement l'auteur, vous appelleriez votre méthode REST/SolrNet.

En règle générale, si vous demandez "Devrais-je utiliser Solr ou le faire moi-même?" la réponse est presque toujours "utiliser Solr". Je ne peux pas penser à aucune raison que vous voudriez le faire vous-même ici, à moins que votre jvm soit vraiment mauvais ou que vous détestiez vraiment Java.

2

En supposant que vous utilisez Java - j'ai eu de bonnes expériences d'indexation en utilisant plusieurs threads. Dans mon expérience, l'indexation de Lucene est liée au processeur, ce qui signifie que si vous générez N threads, vous pouvez utiliser tous vos N cœurs.

Le Lucene IndexWriter gère la concurrence de sorte que vous n'avez pas à vous en préoccuper. Vos discussions peuvent simplement appeler indexWriter.addDocument dès qu'elles sont prêtes à le faire.

Dans un projet, les documents provenaient d'une instruction SELECT provenant d'une base de données. J'ai créé N threads et chacun a pris le document suivant du ResultSet et l'a ajouté à l'index. Le thread s'est terminé quand il n'y avait plus de lignes et le thread principal a attendu sur un CountDownLatch.

Le deuxième projet était un peu plus complexe. Le système «rampait» un ensemble de documents, c'est-à-dire qu'il n'était pas clair dès le début combien de documents il allait y avoir. Il était donc nécessaire de maintenir une "file" de documents déjà découverts. Et lors de l'analyse et de l'indexation de ces documents, il a été possible de découvrir plus de documents qui ont ensuite été ajoutés à la file d'attente. La file d'attente a été remplie au début avec le document initial/seed. J'ai créé une classe AutoStopThreadPool pour gérer les discussions, vous êtes les bienvenus à download si vous le souhaitez. (Les pools de threads JVM vous devez "ajouter" toutes les tâches puis "attendre la fin", ce qui ne convenait pas car le traitement d'une tâche pouvait entraîner la découverte de nouvelles tâches)