Como arquitetar um programa que lidará com análise de milhões de objetos?

5 respostas
diego_qmota

Boa noite

Gostaria de dicas para uma arquitetura da seguinte forma:

Um sistema que irá manipular uma quantidade gigantesca de objetos (milhões) para fazer cálculos e gerar relatório dos cálculos efetuados.

Os cálculos não são intuitivos, exigindo lógica de programação.
Não são bem cálculos simples mas sim análises para verificar se há discrepâncias nos dados que os objetos indicam e o que foi parametrizado. Deve parar se alcançado determinada quantia, comparar diversos índices, seguir várias regras, etc
Então, usando consultas SQL (SUM, COUNT, MAX…) não irá resolver…são cálculos que exigirão uma lógica de programação pesada em cima.

Estava pensando o que seria melhor… serializar esses objetos, armazenando em um arquivo texto e lendo esse arquivo quando fosse efetuado os cálculos, dessa forma estaria cuidando do gerenciamento da memória (para evitar estouro)
Ou recuperá-los de um bd. O problema é que aí haveria lentidão…já que os cálculos exigiriam que eu percorresse registro a registro, recolhesse os dados do objeto, efetuasse os calculos e … próximo registro.

Eu estava pensando também em usar banco orientado a objeto…não sei se supriria esse problema…

Ressaltando: Os milhões de objetos devem ser descartáveis. Não quero armazená-los para depois, são para uso na hora da análise. Depois que eu fizer os cálculos e salvar um detalhamento da análise, eu iria descartar todos quando fosse feita uma nova análise.

Resumindo: Preciso de uma forma simples de manipular milhões de objetos para analisá-los e depois jogá-los fora, da mesma forma como faço com um array de 10 objetos com lógica de programação…

5 Respostas

danieldomingues86

Olá

Olha não sei se resolveria o seu caso, mas acredito que uma opção seria criar uma aplicação distribuída
e dividir o processamento para manipular seus objetos em um ambiente de cluster.

Assim voce aumentaria a capacidade de processamento e consequentemente evitaria o estouro de memória.

Um Abraço.

peczenyj

Experimente utilizar um banco de dados não relacional distribuido como um MongoDB ou CouchDB e trabalhe com map reduce distribuido. O seu problema parece ser memoria e velocidade de acesso portanto as tecnicas adequadas de cache e de simplificação de resultados podem ser cruciais. Tente pensar numa arquitetura “shared nothing” para escalar de forma quase perfeita, talvez ate usando uma linguagem funcional como Haskell, lisp ou Scala - esta ultima roda sob a jvm.

http://blog.caelum.com.br/2009/10/30/bancos-de-dados-nao-relacionais-e-o-movimento-nosql/

Por outro lado a sua aplicação pode não ser tão complexa quanto vc pensa, ainda mais se vc usar um hibernate tunado, fazendo um bom uso de second level cache e lazy inicialization. :wink:

diego_qmota

danieldomingues86:
Olá

Olha não sei se resolveria o seu caso, mas acredito que uma opção seria criar uma aplicação distribuída
e dividir o processamento para manipular seus objetos em um ambiente de cluster.

Assim voce aumentaria a capacidade de processamento e consequentemente evitaria o estouro de memória.

Um Abraço.

Obrigado pela sugestão Daniel, mas esqueci de mencionar que os recursos também são excassos…rsrs.
Não preciso de tudo isso… porquê o aplicativo será DESKTOP e deverá rodar um em cada máquina.

Temos um programa em VB que executa essa tarefa… mas por ser programa procedural, têm muitas, muitas linhas de código bem confuso e difícil de alterar. Um cara que fez em VB esse módulo e hoje eu faço a manutenção.
Mas mexer com os módulos está se tornando uma tarefa muito árdua…
Daí pensei em algo similar em JAVA…

Ele leva de 10 a 20 minutos para importar os dados de fontes como PDF e TXT e analisá-los.
Não é um tempo ruim para o volume de dados que processa… e faz isso em PC´s até simples demais… Mas castiga a memória RAM dos PCS… :slight_smile:

diego_qmota

peczenyj:
Experimente utilizar um banco de dados não relacional distribuido como um MongoDB ou CouchDB e trabalhe com map reduce distribuido. O seu problema parece ser memoria e velocidade de acesso portanto as tecnicas adequadas de cache e de simplificação de resultados podem ser cruciais. Tente pensar numa arquitetura "shared nothing" para escalar de forma quase perfeita, talvez ate usando uma linguagem funcional como Haskell, lisp ou Scala - esta ultima roda sob a jvm.

http://blog.caelum.com.br/2009/10/30/bancos-de-dados-nao-relacionais-e-o-movimento-nosql/

Por outro lado a sua aplicação pode não ser tão complexa quanto vc pensa, ainda mais se vc usar um hibernate tunado, fazendo um bom uso de second level cache e lazy inicialization. ;-)

Bom, eu não sei usar o HIBERNATE ainda…quando eu aprender… :slight_smile:

Estava pensando em algumas possibilidades dessas:

  • Usar um banco não relacional de forma a processar os dados aos poucos. E ganhar tempo (evitando a tradicional conversão RELACIONAL <-> OO). O banco seria criado/salvo em cada máquina que executasse o programa, evitando banco server e ganhando tempo com a leitura dos dados no disco do PC. Pegaria listas de objetos com tamanho limitado, tipo 10000 objetos do banco (por exemplo), para fazer um processamento segmentado:
    Instanciar 10000 objetos com dados do banco -> processá-los -> limpar a memória -> buscar mais 10000 objetos.

  • Serialização (que não sei fazer ainda, mas que se servir não custa nada aprender :D);

  • Salvar todos os objetos em arquivos XML e usar um processamento segmentado, similar ao do primeiro ítem;

Como seria para fazer usando map reduce distribuido?

Kenobi

Acredito que você poderia fazer uma brincadeira com o EhCache junto ao Hibernate (pra facilitar sua vida) e TerraCota - http://www.terracotta.org/ehcache/distributed-cache/ehcache-ex-hibernate

Fato é, você vai precisar fazer isso em tempo de memória. O Pattern MapReduce também poderia ser usado com o Hadoop, mas isso seria mais leval server-side, como a aplicação é Desktop, seria bacana algo mais simples.

Criado 22 de janeiro de 2010
Ultima resposta 23 de jan. de 2010
Respostas 5
Participantes 4