Bonjour,

J'utilise Solrj pour indexer des documents mais j'ai remarqué un comportement étrange en utilisant la classe ConcurrentUpdateSolrServer. Mon objectif est d'atteindre une vitesse d'indexation de 15000 documents par seconde.

J'ai installé une instance de Solr sur une machine virtuelle distante (VM) sur Linux avec 8 CPUs et j'ai implémenté un programme Java sur mon ordinateur en utilisant Eclipse. Je vais décrire 2 scénarios que j'ai réalisé pour expliquer mon problème :

Scénario 1 :

J'ai exécuté mon programme Java via Eclipse en définissant mon serveur Solr en passant l'adresse de ma VM pour indexer ma collection de documents comme ceci :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
String url = "http://10.35.1.72:8080/solr/";
ConcurrentUpdateSolrServer server = new  ConcurrentUpdateSolrServer(url,4000,20);
Puis, j'ai ajouté mes documents en créant une classe java qui étends la classe Thread :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
@Override
public void run(){
SolrInputDocument doc = new SolrInputDocument();
/*
 * Processing on document to add fields ...
 */
UpdateResponse response = server.add(doc);
 
/*
 * Response's Analysis 
 */
Pour éviter d'ajouter les documents de manière séquentielle, j'ai utilisé un Executor (classe Java) afin d'ajouter mes documents de manière parallèle :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
Executor executor = Executors.newFixedThreadPool(nbThreads);
for (int j = 0; j < myfileList.size(); j++) {
     executor.execute(new myclassThread(server,new myfileList(j)));
}
Quand j'exécute ce programme, le résultat est correct car tout les documents sont bien indexés dans les indexes de Solr/Lucene. Je peux le voir en regardant le Solr Admin :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
Results :
numDocs: 3588
maxDoc: 3588
deletedDocs: 0
Le problème est que les performances d'indexation sont médiocre (vitesse d'indexation lente) comparées à une indexation sans utiliser Solrj et en indexant directement sur la VM (en utilisant la commande CURL en shell pour les updates de documents). C'est pourquoi, j'ai créé un fichier JAR de mon programme via eclipse pour l'exécuter sur ma VM.

Scénario 2 :

J'ai donc généré ce fichier JAR et je les exécuté sur ma VM distante. J'ai changé l'adresse de mon server Solr comme ci dessous :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
 
String url = "http://localhost:8080/solr/";
ConcurrentUpdateSolrServer server = new  ConcurrentUpdateSolrServer(url,4000,20);
J'ai exécuté mon fichier JAR avec la même collection de documents (3588 documents avec une clé unique) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
java -jar myJavaProgram.jar
Et le résultat dans Solr Admin est :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
Results :
numDocs: 2554
maxDoc: 3475
deletedDocs: 921
Ce résultat dépend du paramétrage du nombres de threads (associés à l'Executor et au ConcurrentUpdateSolrServer). Pour finir, tous mes documents ne sont pas indexés mais la vitesse d'indexation est bien meilleure. Je suppose que l'ajout des documents dans le serveur est trop rapide et donc j'obtiens des pertes. J'ai essayé de ralentir l'indexation en ajoutant un Thread.sleep(temps), mais cela n'a pas changer le problème.

Je n'ai pas réussi à paramétrer correctement mes threads. peu importe si je mais beaucoup ou peu de threads, dans tous les cas, j'ai des pertes.

Questions :

- Est-ce que quelqu'un a déjà entendu parler de problèmes similaires avec la classe ConcurrentUpdateSolrServer ?
- Y a-t-il une explication a ces pertes ? Pourquoi tous mes documents ne sont pas indexés dans le second scénario ? Et pourquoi, quelques documents sont supprimés même si tout mes documents ont une clé unique ?
- Y a-t-il un moyen correct pour indexer des documents de manière ascynchrone (non séquentielle) avec Solrj ?
- J'ai vu qu'il existait une classe de Solrj pour indexer les données : EmbeddedSolrServer. Est-ce que cette classe permet d'améliorer la vitesse d'indexation ou est-elle plus adaptée pour mon cas ?
- Quand j'analyse la réponse de la méthode add() du serveur Solr, j'ai remarqué que la réponse était toujours bonne (response.getstatut()=0) alors que ce n'est pas le cas car mes documents ne sont pas correctement indexé. Est-ce que ce comportement de la méthode add() est normal ou non ?

Pour finir, si vous avez une idée sur mon problème ou bien si vous avez une idée sur la manière d'indexer rapidement des documents (en utilisant au maximum les ressources de mes processeurs) via solrj, j'en serais ravi !

Merci

Corentin