2009-06-03 19 views
12

estamos diseñando la arquitectura de búsqueda para una aplicación web corporativa. Usaremos Lucene.net para esto. Los índices no serán grandes (aproximadamente 100.000 documentos), pero el servicio de búsqueda siempre debe estar actualizado y siempre actualizado. Habrá nuevos documentos agregados al índice todo el tiempo y búsquedas simultáneas. Como debemos tener una alta disponibilidad para el sistema de búsqueda, tenemos 2 servidores de aplicaciones que exponen un servicio WCF para realizar búsquedas e indexar (se está ejecutando una copia del servicio en cada servidor). El servidor luego usa la API de lucene.net para acceder a los índices.Sincronización de índices de Lucene.net en varios servidores de aplicaciones

El problema es, ¿cuál sería la mejor solución para mantener los índices sincronizados todo el tiempo? Hemos considerado varias opciones:

  • El uso de un servidor de indexación y teniendo el segundo servidor de acceso los índices a través de SMB: no puede hacerlo porque tenemos un único punto de fallo situación;

  • Indexación para ambos servidores, esencialmente escribiendo cada índice dos veces: probablemente un rendimiento malo, y la posibilidad de desincronización si, por ejemplo. el servidor 1 indexa OK y el servidor 2 se queda sin espacio en disco o lo que sea;

  • Usando SOLR o KATTA para ajustar el acceso a los índices: no, no podemos tener tomcat o ejecución similar en los servidores, solo tenemos IIS.

  • Almacenamiento del índice de la base de datos: me encontré con esto se puede hacer con la versión Java de Lucene (módulo JdbcDirectory), pero no pude encontrar nada similar para Lucene.net. Incluso si esto significara un pequeño golpe de rendimiento, optaríamos por esta opción porque resolvería limpiamente el problema de simultaneidad y sincronización con el desarrollo mínimo.

  • Uso de Lucene.net DistributedSearch contrib module: No pude archivar un solo enlace con documentación sobre esto. Ni siquiera sé, al mirar el código, qué hace este código, pero me parece que en realidad divide el índice en varias máquinas, que no es lo que queremos.

  • rsync y amigos, copiando los índices de ida y vuelta entre los 2 servidores: esto se siente harto y propenso a errores, y, si los índices crecen, podría llevar un tiempo, y durante este período estaríamos devolviendo datos corruptos o inconsistentes a los clientes, por lo que tendríamos que desarrollar alguna política de bloqueo ad hoc, que no queremos.

Entiendo que este es un problema complejo, pero estoy seguro de que mucha gente lo ha enfrentado anteriormente. Cualquier ayuda es bienvenida!

Respuesta

6

Parece que la mejor solución sería indexar los documentos en ambos servidores en su propia copia del índice.

Si le preocupa que la indexación tenga éxito en un servidor y falle en el otro, entonces tendrá que hacer un seguimiento del éxito/falla de cada servidor para que pueda volver a intentar los documentos fallidos una vez que el problema esta resuelto. Este seguimiento se realizaría fuera de Lucene en cualquier sistema que esté utilizando para presentar los documentos que se indexarán a Lucene. Dependiendo de qué tan crítico sea para usted la integridad del índice, también puede tener que eliminar el servidor que falló de cualquier equilibrador de carga que esté utilizando hasta que el problema haya sido resuelto y la indexación haya reprocesado los documentos pendientes.

+0

Sean, esta es actualmente nuestra opción de candidato. Estoy de acuerdo contigo y con ella en que parece ser la mejor elección. También estoy tratando de encontrar las fuentes de JdbcDirectory para ver si un puerto al servidor .NET + SQL sería factible. Mantendrá la pregunta abierta por un tiempo para ver si surgen nuevos enfoques, aceptará esta respuesta de lo contrario. –

+0

Comprobé lo mismo una vez. No parecía valer la pena el esfuerzo, ya que hay un montón de cosas relacionadas con la transacción de BD que no es trivial para portar a .Net. También hubo quejas de velocidad reducida usando el material de JDBCDirectory. La fuente está en el proyecto Brújula - http://svn.compass-project.org/svn/compass/trunk/src/main/src/org/apache/lucene/store/jdbc/ –

+2

Después de pensar un poco, esto es lo Veo como la solución más viable: cuando se recibe una solicitud de indexación/desinsecación, inserte una fila en una tabla de base de datos compartida que funcione como una cola. Implemente un servicio win32 simple que se ejecute en ambos servidores de aplicaciones y sondee la cola cada X segundos, indexando el contenido localmente. Cuando el contenido se indexa con éxito, el servicio marca el elemento como procesado, de lo contrario, sigue intentándolo. –

1

+1 por la respuesta de Sean Carpenter. La indexación en ambos servidores parece ser la elección más segura y segura.

Si los documentos que indexa son complejos (Word/PDF y los géneros), podría realizar un preprocesamiento en un único servidor y luego entregarlo a los servidores de indexación para ahorrar tiempo de procesamiento.

Una solución que he usado antes implica la creación de un trozo de índice en un servidor, a continuación, rsync ing la vuelta a los servidores de búsqueda y la fusión de la porción en cada índice, usando IndexWriter.AddIndexesNoOptimize. Puede crear un nuevo fragmento cada 5 minutos o cada vez que alcanza un determinado tamaño. Si no tiene que tener índices absolutamente actualizados, esta podría ser una solución para usted.

1

en el mundo de Java, hemos resuelto este problema al poner un MQ delante del índice (es). El inserto solo se completó cuando el frijol sacado de la cola fue exitoso, de lo contrario simplemente revertía cualquier acción que tomara, marcado en el documento como pendiente y probado nuevamente más tarde

1

Sé que esta es una vieja pregunta, pero acabo de encontrarlo y quería dar mis 2 centavos por cualquier persona que busque asesoramiento en una implementación de servidores múltiples.

Por qué no mantener los archivos de índice en una carpeta compartida NAS? ¿En qué se diferencia del almacenamiento del índice en una base de datos que estaba contemplando? Una base de datos puede replicarse para alta disponibilidad, ¡y también puede ser un NAS!

Configuraría los dos servidores de aplicaciones que tiene detrás de un equilibrador de carga. Cualquier solicitud de índice que ingrese indexará documentos en una carpeta específica de la máquina en el NAS. Es decir, habrá tantos índices en el NAS como servidores de aplicaciones. Cuando ingrese una solicitud de búsqueda, realizará una búsqueda de múltiples índices utilizando Lucene. Lucene tiene construcciones (MultiSearcher) integradas para hacer esto, y el rendimiento es excelente.

+0

no he verificado si esto es cierto o no, pero la siguiente respuesta dice que "una de las principales recomendaciones de Lucene es no utilizar los sistemas de archivos en red": http://stackoverflow.com/a/8562566/1145177 El Las FAQ de Lucerne mencionan "Usar un sistema de archivos local. Los sistemas de archivos remotos son generalmente un poco más lentos para buscar. Si el índice debe ser remoto, intente montar el sistema de archivos remoto como un montaje de solo lectura": http://wiki.apache.org/ lucene-java/ImproveSearchingSpeed –

0

La forma en que mantenemos sincronizados nuestros servidores con equilibrio de carga, cada uno con su propia copia de Lucene, es tener una tarea en otro servidor, que se ejecuta cada 5 minutos para que cada servidor de carga equilibrada actualice su índice a una cierta marca de tiempo Por ejemplo, la tarea envía una marca de tiempo de '12/1/2013 12: 35: 02.423 'a todos los servidores con equilibrio de carga (la tarea es enviar la marca de tiempo a través de querystring a una página web en cada sitio web con equilibrio de carga).), cada servidor utiliza esa marca de tiempo para consultar en la base de datos todas las actualizaciones que se han producido desde la última actualización hasta esa marca de tiempo y actualiza su índice Lucene local.

Cada servidor también almacena la marca de tiempo en la base de datos, por lo que sabe cuándo se actualizó por última vez cada servidor. Entonces, si un servidor se desconecta, cuando vuelve a estar en línea, la próxima vez que reciba un comando de marca de tiempo, obtendrá todas las actualizaciones que perdió mientras estaba fuera de línea.

Cuestiones relacionadas