Juan,
Essa questão é muito complexa.
poste essa duvida no dotnetscientist
Em 27/04/12, Juan Lopes<
m...@juanlopes.net> escreveu:
> Galera, desculpe pela pergunta longa, mas não consegui forma mais sucinta
> de explicar o meu problema.
> *
> *
> *Contexto:*
>
> Estou desenvolvendo um sistema que indexa full-text um grande volume de
> dados. Estou usando o Lucene (para Java) como backend. Esse sistema já é
> capaz de indexar (em cluster) algumas dezenas de TB por dia. Cada nó do
> cluster atualmente suporta 1~2TB/dia a uma taxa de 10~20MB/s. Cada registro
> desse sistema é relativamente pequeno (variando entre 100 e 500 bytes).
>
> Como o volume de indexação desse sistema é muito grande, algumas
> otimizações foram feitas para limitar o tamanho do índice. Não estou
> armazenando termvectors, freqs, norms, nem nada do Lucene além do
> necessário. Basicamente meu índice só é capaz de dizer quais documentos
> batem com uma busca (de forma binária, sem score).
>
> Além disso, como os registros são bem pequenos (e de cardinalidade bem
> alta), evitamos o overhead da criação de documentos no lucene agrupando
> esses registros em pacotes de tamanho configurável. Normalmente são pacotes
> com 1000 ou 10000 registros. Ou seja, a cada 1000 registros, é gerado
> apenas um documento no Lucene com todos os termos para todos os registros
> do pacote. E cada pacote é armazenado no disco de forma independente. Com
> isso, conseguimos manter o índice do Lucene ocupando cerca de 0.5% do total
> de dados indexados. Está sendo suficiente.
>
> Assim, beneficiando a indexação, penalizamos a busca ao exigir que a cada
> busca, o Lucene seja apenas um guia para indicar quais pacotes abrir, mas é
> necessário verificar em cada pacote quais mensagens dele de fato batem com
> a busca que foi realizada.
>
> Além disso, vários processos do sistema exigem que seja possível verificar
> para cada registro, se uma certa busca do Lucene dá match com ele.
>
> *Então:*
>
> Tenho um mecanismo bastante rudimentar fora do Lucene para verificar para
> cada registro se uma query do Lucene dá match. Basicamente consiste em
> percorrer o modelo de objetos da query do Lucene criando objetos
> correspondentes que simulem essa query em real-time. Mais uma vez: sem usar
> os documentos do Lucene. Os objetos dessa query eu chamo de "predicates" e
> são basicamente um objeto que tenha um método "evaluate" para dizer se um
> conjunto de tokens aceita ou não essa query. O correspondente ao TermQuery
> é algo como isso:
https://gist.github.com/2510623
>
> Até agora, isso estava sendo suficiente, pois o volume de queries era
> bastante baixo, porém, mais processos começaram a precisar desse mecanismo
> para verificar as mensagens em tempo real. Processos que executam ainda
> durante a indexação (sem relação com o usuário), como agregação e
> enriquecimento de mensagens e o que era algo simples começou a ficar
> bastante custoso na feature principal do sistema (que repito, é a
> indexação).
>
> O ponto aqui não é o fato de que um predicate seja custoso, mas sim que
> existam várias queries parecidas rodando sobre o mesmo set de dados
> repetidamente.
>
> Percebemos também que apesar de um conjunto de 1000 documentos geralmente
> ter cerca de 30000 tokens, apenas cerca de 2000 deles são distintos. E
> pensamos que talvez valha a pena aproveitar isso.
>
> *A pergunta:*
>
> Existe alguma forma conhecidamente fácil de gerar um índice (fora do
> Lucene) volátil pra cada um desses pacotes e consultá-los de forma barata.
> Quero dizer, percorrer uma única vez todos os termos de todos os registros
> de um pacote para gerar um índice reverso. Índice que possa ser usado por
> algumas centenas de consultas para determinar quais registros num pacote
> batem com ela sem ter que percorrer novamente os tokens?
>
> Tenho na manga, caso nada funcione, como implementar na mão uma árvore de
> sufixos (bastante parecida com a que o Lucene faz, mas otimizada para o meu
> caso), já até fiz um protótipo e funciona bem, mas quero fugir um pouco do
> NIH e ver se já existe alguma solução de consulta em realtime que seja tão
> eficiente quanto o próprio Lucene.
>
> *O que é importante ter em mente:*
>
> A taxa de indexação atualmente é de cerca de 20MB/s, o que significa entre
> 100~200 mil registros por segundo. Ou seja, 100~200 pacotes por segundo.
>
> Já tentamos usar o próprio Lucene com um RAMDirectory para gerar esse
> índice. Mas o overhead de criação do índice é alto, não rola fazer 150~200
> vezes por *segundo.*
>
> As queries são queries do Lucene. Ou seja, não basta dizer se o documento
> tem ou não aquele termo. Tem que suportar PrefixQuery, WildcardQuery,
> FuzzyQuery, RangeQuery, etc.
>
> --
>
https://github.com/juanplopes
>
> --
> Você recebeu esta mensagem porque faz parte do grupo .Net Architects
> hospedado no Google Groups.
> Para postar envie uma mensagem para
dotnetar...@googlegroups.com
> Para sair do grupo envie uma mensagem para
>
dotnetarchitec...@googlegroups.com
> Para mais opções visite o grupo em
>
http://groups.google.com/group/dotnetarchitects?hl=pt-br