2011-08-25 5 views
25

J'ai beaucoup cherché pour voir comment utiliser MongoDB en combinaison avec Solr, et quelques questions ici ont des réponses partielles, mais rien de vraiment concret (plutôt comme des théories). Dans mon application, je vais avoir beaucoup, beaucoup de documents stockés dans MongoDB (peut-être jusqu'à quelques centaines de millions), et je veux implémenter des recherches en texte intégral sur certaines propriétés de ces documents, donc je suppose que Solr est la meilleure ce.java - MongoDB + Performances de Solr

Ce que je veux savoir, c'est comment dois-je configurer/exécuter tout pour avoir de bonnes performances? En ce moment, voici ce que je fais (et je sais que ce ne est pas optimale):

1- Lors de l'insertion d'un objet dans MongoDB, je puis l'ajouter à Solr

SolrServer server = getServer(); 
SolrInputDocument document = new SolrInputDocument(); 
document.addField("id", documentId); 
... 
server.add(document); 
server.commit(); 

2- Lors de la mise à jour d'une propriété du objet, depuis Solr ne peut pas mettre à jour un seul champ, d'abord je récupère l'objet de MongoDB puis mettre à jour l'index Solr avec toutes les propriétés de l'objet et de nouveaux et faire quelque chose comme

StreamingUpdateSolrServer update = new StreamingUpdateSolrServer(url, 1, 0); 
SolrInputDocument document = new SolrInputDocument(); 
document.addField("id", documentId); 
... 
update.add(document); 
update.commit(); 

3- Lors de l'interrogation, d'abord je fais une recherche Solr et puis lors de la récupération de la liste des documents SolrDocumentList Je passe par chaque document et:

  1. obtenir l'ID du document
  2. obtenir l'objet de MongoDB ayant le même identifiant pour pouvoir récupérer les propriétés à partir de là

4- Lorsque supprimer, bien je n'ai pas encore fait cette partie et pas vraiment sûr comment le faire en Java

Alors quelqu'un a des suggestions sur la façon de le faire de manière plus efficace pour chacun des scénarios décrits ici? Comme le processus pour le faire de telle sorte qu'il ne faudra pas 1 heure pour reconstruire l'index quand il y a beaucoup de documents dans Solr et en ajoutant un document à la fois? mes exigences ici sont que les utilisateurs peuvent vouloir ajouter un document à la fois, plusieurs fois et je voudrais qu'ils soient en mesure de le récupérer juste après

+0

Quelle est la taille de chaque document et les propriétés que vous souhaitez indexer? –

+0

@JustinThomas - Eh bien, chaque document peut avoir environ 10 propriétés, certaines d'entre elles peuvent être de longues descriptions et je voudrais indexer pour la recherche en texte intégral sur la description, juste la correspondance exacte sur les autres. Est-ce que ça répond à votre question? – Guillaume

Répondre

14

Votre approche est réellement bonne. Certains frameworks populaires comme Compass effectuent ce que vous décrivez à un niveau inférieur afin de refléter automatiquement les changements d'index qui ont été effectués via le framework ORM (voir http://www.compass-project.org/overview.html). En plus de ce que vous décrivez, je voudrais également ré-indexer régulièrement toutes les données qui se trouvent dans MongoDB afin de synchroniser Solr et Mongo (probablement pas aussi longtemps qu'on pourrait le penser, en fonction de nombre de documents, le nombre de champs, le nombre de jetons par domaine et la performance des analyseurs: je crée souvent des index de 5 à 8 millions de documents (environ 20 champs, mais les champs de texte sont courts) en moins de 15 minutes analyseurs, assurez-vous que votre mémoire tampon n'est pas trop petite et ne validez pas/optimisez jusqu'à ce que tous les documents aient été ajoutés). En ce qui concerne les performances, une validation est coûteuse et une optimisation est très coûteuse. En fonction de ce qui vous importe le plus, vous pouvez modifier la valeur du mergefactor dans Solrconfig.xml (les hautes valeurs améliorent les performances d'écriture alors que les faibles valeurs améliorent les performances de lecture, 10 est une bonne valeur pour commencer).

Vous semblez avoir peur du temps de construction de l'index. Cependant, comme le stockage des index Lucene est basé sur des segments, le débit d'écriture ne doit pas dépendre trop de la taille de l'index (http://lucene.apache.org/java/2_3_2/fileformats.html).Cependant, le temps d'échauffement augmentera, donc vous devez vous assurer que

  • il y a des typiques (en particulier pour les tris pour charger les fieldcaches), mais pas les requêtes trop complexes dans les paramètres firstSearcher et newSearcher dans votre solrconfig. fichier de configuration XML,
  • useColdSearcher est réglé sur
    • faux afin d'avoir de bonnes performances de recherche, ou
    • vrai si vous souhaitez que les modifications effectuées à l'indice à prendre rapidement en compte au prix d'une recherche plus lente .

De plus, si elle est acceptable pour vous si les données devient consultable en quelques millisecondes X après qu'il a été écrit à MongoDB, vous pouvez utiliser la fonction commitWithin de UpdateHandler. De cette façon, Solr devra s'engager moins souvent.

Pour plus d'informations sur les facteurs de performance Solr, voir http://wiki.apache.org/solr/SolrPerformanceFactors

Pour supprimer des documents, vous pouvez supprimer par ID du document (tel que défini dans schema.xml) ou par requête: http://lucene.apache.org/solr/api/org/apache/solr/client/solrj/SolrServer.html

+0

bon point sur le 'deleteById', je ne l'ai pas vu en fait (n'a même pas essayé de je dois dire, j'ai supposé qu'il y avait quelque chose de plus compliqué). Depuis que vous semblez en savoir beaucoup à ce sujet, un peu plus de question si cela ne vous dérange pas: 1. combien est un bon tampon de RAM? 2. Je n'ai pas changé firstSearcher et newSearcher pour l'exemple de fichier solrconfig.xml, sont-ils bons? 3. enfin, j'ai une instance de solr fonctionnant sous tomcat, 5 cœurs dedans. Cela change-t-il quelque chose en ce qui concerne les performances pour avoir plus d'une instance de solr? merci pour votre aide – Guillaume

+0

1. Vous devez effectuer quelques tests pour trouver la meilleure taille de tampon. Je vous recommande de commencer avec 32M et doublez la quantité de mémoire disponible pour le tampon RAM à chaque itération, arrêtez lorsque l'augmentation de la taille du tampon RAM ne donne pas d'amélioration significative. – jpountz

+0

2. Ils ne le sont pas: Charger des caches de champs (requis pour les requêtes de sortes et de fonctions entre autres) prend du temps avec Solr, par conséquent, la première requête qui utilisera des caches sur un nouvel index aura une pénalité de performance. mettre des requêtes qui vont charger ces caches de champ (juste mettre une requête qui effectue des tris sur les mêmes champs que votre application) dans newSearcher et firstSearcher. – jpountz

1
  1. Vous pouvez également attendre plus de documents et ne les indexer que toutes les X minutes. Si vos documents sont petits et que vous n'avez pas besoin de toutes les données (qui sont stockées dans MongoDB), vous pouvez mettre uniquement le champ dont vous avez besoin dans le document Solr par: http://www.mongoddb.com/docs/default.aspx?displaylang=en&displaylang=en&displaylang=en&displaylang=en&displaylang=en&displaylang=en les stocker, mais pas l'indexation

<field name="nameoyourfield" type="stringOrAnyTypeYouuse"indexées="false"stockées="true"/>

Questions connexes