Caso um índice ser otimizado após índices incrementais em Lucene?
-
02-07-2019 - |
Pergunta
executar re-índices completos a cada 7 dias (isto é, a criação do índice do zero) no índice Lucene e índices incrementais a cada 2 horas ou mais. Nosso índice tem cerca de 700.000 documentos e um índice completo leva cerca de 17 horas (o que não é um problema).
Quando fazemos índices incrementais, só conteúdo índice que mudou nas últimas duas horas, por isso leva muito menos tempo - cerca de meia hora. No entanto, temos notado que um monte de este tempo (talvez 10 minutos) é gasto de executar o método IndexWriter.optimize ().
O LuceneFAQ menciona que:
A classe IndexWriter suporta um método optimize () que compacta o banco de dados de índice e acelera consultas. Você pode querer usar este método depois de realizar uma indexação completa do seu conjunto de documentos ou após atualizações incrementais do índice. Se a sua atualização parcial acrescenta documentos com freqüência, você deseja executar a otimização só de vez em quando para evitar a sobrecarga extra do optimization.
... mas isso não parece dar qualquer definição para o que significa "freqüentemente". Otimizando é intensivo da CPU e muito IO-intensiva, por isso prefiro não estar fazendo isso, se podemos fugir com ele. Quanto é o hit da execução de consultas em um índice-un otimizado (Estou pensando especialmente em termos de desempenho da consulta depois de um re-índice cheio em comparação com após 20 índices incrementais onde, digamos, 50.000 documentos foram alterados)? Devemos ser otimizar após cada índice incremental ou é o desempenho não atingiu vale a pena?
Solução
Mat, uma vez que parece que você tem uma boa idéia de quanto tempo o processo atual leva, eu sugiro que você remova o optimize()
e medir o impacto.
fazer muitas das mudanças documentos nessas janelas de 2 horas? Se apenas uma pequena fração (50.000 / 700.000 é de cerca de 7%) são gradativamente re-indexados, então eu não acho que você está recebendo muito valor fora de um optimize()
.
Algumas ideias:
- Não faça um
optimize()
incrementais em tudo. Minha experiência diz que você não está vendo uma melhora consulta enorme de qualquer maneira. - Faça o
optimize()
diária em vez de 2-horária. - Faça o
optimize()
durante tempos de baixo volume (que é o que o javadoc diz).
E certifique-se de fazer as medições. Esses tipos de mudanças pode ser um tiro no escuro sem eles.
Outras dicas
Uma operação optimize
lê e escreve o índice inteiro, razão pela qual é tão IO intensivo!
A idéia por trás operações otimizar é a re-combinar todos os vários segmentos no índice Lucene em um único segmento, que pode reduzir significativamente consulta vezes você não tem que abrir e procurar vários arquivos por consulta. Se você estiver usando a estrutura normal Lucene arquivo de índice (em vez da estrutura combinada), você começa um novo segmento por comprometer a operação; o mesmo que o seu re-índices eu presumo?
Matt tem grande conselhos e eu tinha segundo tudo o que ele diz - ser impulsionado pelos dados que ter. Eu gostaria realmente dar um passo adiante e só optmize a) quando você precisa e b) quando você tem baixo volume de consulta.
Como o desempenho da consulta está intimamente ligada com o número de segmentos em seu índice, um ls -1 index/segments_* | count
simples poderia ser um indicador útil para quando na otimização é realmente necessário.
Como alternativa, acompanhando o desempenho da consulta e volume e dando início a uma otimizar quando você atingir o desempenho inaceitável baixo com aceitavelmente baixo volume seria uma solução mais agradável.
Na este e-mail , conselhos Otis Gospodnetic contra usando otimizar, se o índice está vendo atualizações constantes. É a partir de 2007, mas chamando optimize()
está em sua própria natureza, uma operação IO-pesados. Você poderia considerar o uso de uma abordagem mais gradual; um MergeScheduler