2008-09-23 9 views
15

Ejecutamos re-índices completos cada 7 días (es decir, la creación del índice desde cero) en nuestro índice Lucene y los índices incrementales cada 2 horas más o menos. Nuestro índice tiene alrededor de 700,000 documentos y un índice completo demora alrededor de 17 horas (lo cual no es un problema).¿Debería optimizarse un índice después de los índices incrementales en Lucene?

Cuando hacemos índices incrementales, solo indexamos contenido que ha cambiado en las últimas dos horas, por lo que toma mucho menos tiempo, alrededor de media hora. Sin embargo, hemos notado que una gran cantidad de este tiempo (quizás 10 minutos) se usa para ejecutar el método IndexWriter.optimize().

El LuceneFAQ menciona que:

La clase IndexWriter apoya un método optimize() que compacta la base de datos de índice y acelera consultas. Es posible que desee utilizar este método después de realizar una indexación completa de su conjunto de documentos o después de las actualizaciones incrementales del índice. Si su actualización incremental agrega documentos con frecuencia, desea realizar la optimización solo de vez en cuando para evitar la sobrecarga adicional de la optimización.

... pero esto no parece dar ninguna definición de lo que significa "con frecuencia". La optimización es intensiva en CPU y MUY IO-intensiva, por lo que preferiríamos no hacerlo si podemos salirse con la suya. ¿Cuánto cuesta la ejecución de consultas en un índice no optimizado (estoy pensando especialmente en términos de rendimiento de la consulta después de un nuevo índice completo en comparación con después de 20 índices incrementales donde, digamos, 50,000 documentos han cambiado)? ¿Deberíamos estar optimizando después de cada índice incremental o el rendimiento alcanzado no lo vale?

Respuesta

16

Mat, ya que parece que tiene una buena idea de cuánto tiempo lleva su proceso actual, le sugiero que elimine el optimize() y mida el impacto.

¿Cambian muchos de los documentos en esas ventanas de 2 horas? Si solo una pequeña fracción (50,000/700,000 es aproximadamente 7%) se vuelven a indexar gradualmente, entonces no creo que esté obteniendo mucho valor de un optimize().

Algunas ideas:

  • no hago un incremento optimize() en absoluto. Mi experiencia dice que, de todos modos, no se ve una gran mejora en la consulta.
  • Haga el optimize() diariamente en lugar de 2 horas.
  • Haga optimize() durante tiempos de bajo volumen (que es lo que dice el javadoc).

Y asegúrese de tomar medidas. Este tipo de cambios pueden ser un tiro en la oscuridad sin ellos.

+0

Este tipo de cambios * son * disparos en la oscuridad sin ellos. –

+0

Saludos, supongo que me preguntaba si la gente tenía experiencia en esto antes de sumergirme y comencé a jugar con un sistema de producción :) –

+0

Mat: sí, me doy cuenta de que estabas buscando un consejo específico, y estaba siendo un poco general. En mi experiencia (he estado usando Lucene durante años) estarás bien sin la optimización(). He eliminado correctamente el optimize() de nuestros sistemas debido a su sobrecarga. –

4

Una operación optimize lee y escribe todo el índice, ¡por eso es tan intensivo en IO!

La idea detrás es optimizar las operaciones para volver a combinar todos los diferentes segmentos en el índice Lucene en un solo segmento, que puede reducir considerablemente los tiempos de consulta y cuando no se tiene que abrir y buscar varios archivos por consulta. Si está utilizando la estructura de archivos de índice Lucene normal (en lugar de la estructura combinada), obtiene un nuevo segmento por operación de confirmación; lo mismo que su re-indexes supongo?

Creo que Matt tiene un gran consejo y yo diría en segundo lugar todo lo que dice, guíese por los datos que tiene.De hecho, iría un paso más allá y solo optimizaría a) cuando lo necesite yb) cuando tenga un volumen de consulta bajo.

Como el rendimiento de la consulta está íntimamente ligado al número de segmentos en su índice, un simple ls -1 index/segments_* | count podría ser un indicador útil para cuando la optimización es realmente necesaria.

Como alternativa, el seguimiento del rendimiento y el volumen de la consulta y la puesta en marcha de una optimización cuando se alcanza un bajo rendimiento inaceptable con un volumen aceptablemente bajo sería una solución más agradable.

2

En this mail, Otis Gospodnetic aconseja contra usando optimize, si su índice está viendo actualizaciones constantes. Es de 2007, pero llamar al optimize() es una operación de IO-heavy. Podría considerar usar un enfoque más gradual; a MergeScheduler

Cuestiones relacionadas