2011-08-25 11 views
25

He estado buscando mucho para ver cómo usar MongoDB en combinación con Solr, y algunas preguntas aquí tienen respuestas parciales, pero nada realmente concreto (más como teorías). En mi aplicación, tendré muchos y muchos documentos almacenados en MongoDB (tal vez hasta unos cientos de millones), y quiero implementar búsquedas de texto completo en algunas propiedades de esos documentos, así que supongo que Solr es la mejor manera de hacerlo esta.java - Funcionamientos de MongoDB + Solr

Lo que quiero saber es cómo debo configurar/ejecutar todo para que tenga un buen rendimiento? en este momento, esto es lo que hago (y yo se que no es óptimo):

1- Al insertar un objeto en MongoDB, que después añadirlo al Solr

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

2- Al actualizar una propiedad de la objeto, ya que Solr no puede actualizar un solo campo, primero recuperar el objeto de MongoDB entonces puedo actualizar el índice Solr con todas las propiedades de objeto y otros nuevos y hacer algo como

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

3- al consultar, primero consulto Solr y luego al recuperar la lista de documentos SolrDocumentList Voy a través de cada documento y:

  1. obtener el ID del documento
  2. obtener el objeto de MongoDB con el mismo ID que ser capaz de recuperar las propiedades de allí

4- Cuando borrando, bueno, no he hecho esa parte todavía y no estoy seguro de cómo hacerlo en Java

¿Alguien tiene sugerencias sobre cómo hacer esto de manera más eficiente para cada uno de los escenarios descritos aquí? ¿Le gusta el proceso para hacerlo de manera que no demore 1 hora reconstruir el índice cuando tiene muchos documentos en Solr y agrega un documento a la vez? mis requisitos aquí son que los usuarios pueden querer agregar un documento a la vez, muchas veces y me gustaría que puedan recuperarlo inmediatamente después de

+0

¿Qué tan grande es cada documento y las propiedades que desea indexar? –

+0

@JustinThomas - bueno, cada documento puede tener alrededor de 10 propiedades, algunas de ellas pueden ser descripciones largas y me gustaría hacer un índice para la búsqueda de texto completo en la descripción, solo coincidencia exacta en las otras. Eso responde tu pregunta? – Guillaume

Respuesta

14

Su enfoque es realmente bueno. Algunos marcos populares como Compass están realizando lo que describes en un nivel inferior para reflejar automáticamente los cambios de índice que se han realizado a través del marco ORM (ver http://www.compass-project.org/overview.html).

Además de lo que describes, también volvería a indexar regularmente todos los datos que viven en MongoDB para asegurar que tanto Solr como Mongo estén sincronizados (probablemente no tanto como se podría pensar, dependiendo del número de documentos, número de campos, cantidad de tokens por campo y rendimiento de los analizadores: a menudo creo índices de 5 a 8 millones de documentos (alrededor de 20 campos, pero los campos de texto son cortos) en menos de 15 minutos con complejos analizadores, solo asegúrate de que tu memoria RAM no es demasiado pequeña y no comprometer/optimizar hasta que se hayan agregado todos los documentos).

En cuanto al rendimiento, una confirmación es costosa y una optimización es muy costosa. Dependiendo de lo que más le importe, puede cambiar el valor de mergefactor en Solrconfig.xml (los valores altos mejoran el rendimiento de escritura, mientras que los valores bajos mejoran el rendimiento de lectura, 10 es un buen valor para empezar).

Parece que le tiene miedo al tiempo de compilación del índice. Sin embargo, dado que el almacenamiento de índices de Lucene está basado en segmentos, el rendimiento de escritura no debe depender demasiado del tamaño del índice (http://lucene.apache.org/java/2_3_2/fileformats.html).Sin embargo, el tiempo de calentamiento se incrementará, por lo que debe asegurarse de que

  • no son típicos (especialmente para las clases con el fin de cargar los fieldcaches), pero las consultas no demasiado complejos en los parámetros firstSearcher y newSearcher en su solrconfig. archivo de configuración XML,
  • useColdSearcher se establece en
    • falsa con el fin de tener un buen rendimiento de la búsqueda, o
    • cierto si desea que los cambios realizados al índice para ser tomado más rápido en cuenta al precio de una búsqueda más lenta .

Por otra parte, si es aceptable para usted si los datos se convierte en búsquedas solamente unos pocos milisegundos X después de que ha sido escrito para MongoDB, puede utilizar la función de commitWithin UpdateHandler. De esta forma, Solr tendrá que comprometerse con menos frecuencia.

Para obtener más información sobre los factores de rendimiento Solr, ver http://wiki.apache.org/solr/SolrPerformanceFactors

Para eliminar documentos, puede eliminar mediante documento de identidad (como se define en schema.xml) o mediante consulta: http://lucene.apache.org/solr/api/org/apache/solr/client/solrj/SolrServer.html

+0

buen punto en el 'deleteById', en realidad no lo vi (ni siquiera lo intenté, debo decir, supuse que había algo más complicado). Dado que parece que sabe mucho al respecto, algunas preguntas más si no le importa: 1. ¿Cuánto es un buen buffer RAM? 2. No cambié el firstSearcher y newSearcher para el archivo de ejemplo solrconfig.xml, ¿están bien? 3. Finalmente, tengo una instancia de solr ejecutándose bajo Tomcat, 5 núcleos. ¿Cambia algo con respecto a las actuaciones para tener más de una instancia de solr corriendo? gracias por su ayuda – Guillaume

+0

1. Necesita realizar algunos puntos de referencia para encontrar el mejor tamaño de búfer para. Recomiendo que empiece con 32M y duplique la cantidad de memoria disponible para el búfer de RAM en cada iteración, deténgalo cuando aumente el tamaño del búfer del ariete que no produce ninguna mejora significativa. – jpountz

+0

2. No lo son: Cargar cachés de campo (requerido para ordenamientos y consultas de funciones entre otros) toma tiempo con Solr, como consecuencia, la primera consulta que usará cachés de campo en un índice nuevo tendrá una penalización de rendimiento, por lo que necesita para poner las consultas que cargarán estos cachés de campo (simplemente ponga una consulta que realice ordenamientos en los mismos campos que su aplicación) en newSearcher y firstSearcher. – jpountz

1
  1. También puede esperar por más documentos e indexarlos solo cada X minutos. (Por supuesto, esto depende mucho de su aplicación & requisitos)

  2. Si sus documentos son pequeños y no necesita todos los datos (que están almacenados en MongoDB) puede poner solo el campo que necesita en el documento de Solr por almacenarlos, pero no la indexación de

<field name="nameoyourfield" type="stringOrAnyTypeYouuse"indexados="false"almacenan="true"/>