Arquitetura para alta performance - Preciso de opinioes!

Galera, mestres e colegas de trabalho! rs

Como não tenho muita experiencia como arquiteto, queria compartilhar com vocês um cenário que estou enfrentando e ouvir opiniões referentes a frameworks, técnicas e tecnologias a serem utilizadas no cenário que irei descrever. PS.: Me desculpe se eu estiver sendo muito genérico em algumas áreas, mas meus chefes querem segredo de estado sobre o sistema. :slight_smile: - Então vamos la.

Tenho um componente javascript que tem duas funções básicas.

1- enviar informações sobre as ações do usuários para um Web-service REST

2- consumir informações do próprio Web-service REST para apresenta-las via requisições ajax.

obs: esse componente foi projetado para ser utilizado em aplicações externas, dos clientes. E isso eh importante mencionar porque no lado do servidor temos uma instancia do facade (core da aplicação) separada para cada contexto (leia-se cada cliente consumidor do serviço). Outro detalhe importante, a chave de identificação do cliente eh enviada de forma criptografada (MD5 provavelmente) no header da requisição HTTP.

No lado do servidor, tenho dois momentos distintos.

1- Um pré-processamento das informações necessárias

2- A partir dos dados pré-processados, consulta-los através da requisição feita pelo componente javascript

Esse segundo momento do lado do servidor trata-se da minha principal duvida atualmente. Que estrategia utilizar para tornar possível essa necessidade de alta velocidade de resposta? E isso impacta na forma como eu eu vou pré-processar minhas informações, pois gostaria de deixa-las no formato mais próximo do ideal para consumo. Algumas indagações minhas ate o momento:

  • Se eu armazenar o resultado do processamento em banco, não tornaria a resposta mais lenta? E se utilizarmos uma estrategia de caching?

  • Pensei em armazenar em um “banco” do tipo chave-valor (ex.: berkeley-db). Mas por questões de licença preciso de outra sugestão que tenha licença LGPL ou Apache 2.0.

Detalhes extra:

Queremos montar uma arquitetura escalar e de boa capacidade de resposta, algo com um throughput entre 50~100 reqs/segundo.

Planejamos hospedar o serviço no cloud da Amazon, EC2, em uma instancia do tipo linux.

Em caso de uso de um banco chave-valor, acho que poderíamos utilizar o Apache Hadoop para mantermos sincronizadas os ?bancos? entre as diversas instancias, isso em caso de necessidade de aumentarmos o número de instancias online em nossa arquitetura, não é!?

Olá

Então deve avaliar dentre as opções possíveis da Amazon. Exemplo: acho que não podera usar o Esper para avalias os dados que chegam na memória sem precisar armazenar tudo na base de dados.

[]s
Luca

O pre-processamento é no mesmo request que a segunda consulta ?
O pre-processamento é unico para várias consultas ? ( ou seja, uma vez pre-processado o resultado pode ser utilizado várias vezes?)

Se o pre-processamento acontece na mesma request e não é único então não é um pré-processamento, é um processamento.

Se o pre-processamento for unico ele pode ser cacheado. Para o cache vc precisa de um java.util.Map mas se vc quiser apelar vc pode usar um framework de cache. O Hadoop não é um framework de cache. Nem um banco de dados é um framework de cache.
Escolha a solução mais próxima do que vc precisa, se vc usar um DB como cache funciona, mas está arquiteturalmente errado.

Se o pre-processamento não tiver que ser sincrono ainda ha a opção de usar um Executor para diminuir a latência.
Além disso ha a opção de usar um cookie que identifique a sessão e utilizar isso para reconhecer o pre-processamento anterior.

[quote]O pre-processamento é no mesmo request que a segunda consulta ?
O pre-processamento é unico para várias consultas ? ( ou seja, uma vez pre-processado o resultado pode ser utilizado várias vezes?)[/quote]

Respondendo:
1- Nao, o pre-processamento acontece a parte, de forma assincrona. Em um momento nao mencionado no cenario aprensentado.
2- Sim, utilizo ele para responder as varias consultas.

[quote]Se o pre-processamento for unico ele pode ser cacheado. Para o cache vc precisa de um java.util.Map mas se vc quiser apelar vc pode usar um framework de cache. O Hadoop não é um framework de cache. Nem um banco de dados é um framework de cache.
Escolha a solução mais próxima do que vc precisa, se vc usar um DB como cache funciona, mas está arquiteturalmente errado.
[/quote]

Concordo que ele pode ser cacheado, mas como ha a expectativa de que tenhamos uma base pre-processada muito grande e inclusive distanta para cada cliente, nao acho que seria conveniente cachearmos atraves de um simples Map por causa da memoria da maquina. Tambem tenho a noçao de que o Hadoop nao eh um banco de dados e muito menos um sistema de caching… Como disse, caso utilizemos um banco chave-valor (ex.:berkeley-db) o mesmo trabalha com arquivos locais em disco, e entao utilizariamos o Hadoop (Apache ZooKeeper que eh um sub-projeto) para manter a sincronizaçao dos mesmos entre as instancias existentes no cloud.

A minha duvida quanto ao cache, esta mais relacionada a questao de utilizarmos um dado especifico no header da requisiçao http, pois ha a possibilidade de haver a mesma url de requisiçao vinda de clientes diferentes.

Como alternativas para o berkeley-db vi dois projetos interessantes: JDBM e o HeliDB. Alguem conhece?

Mais opinioes sao bem-vindas!
Obrigado!

a sua explanação não é nada clara.

Se quer usar chave-valor isso é um tipo de cache. Existem vários frameworks de cache, algums até bem avançados e com persistencia em banco,mas continua sendo um cache. O JCS da apache ou o JBossCache são opções. Mesmo que haja pré-processamento por vários clientes diferentes e para arquivo vc pode usar este mecanismo: as coisas não ficam todas na memória!

Como eu disse, DB funciona, mas não é isso que vc precisa.

Agora, se esse seu “chave-valor” for na realidade “tuplo-tuplo” ai sim DB é mais indicado.

A parte do header tb não entendi. cada requisição tem o seu header. qual é o problema ? ( é a tecnica do cookie que falei antes. o cookie é um tipo especial de header)

P.S. Vc quer uma arquitetura de alta performance sem usar cache em memória ? Fat chance…

Olá

Bem, correndo o risco de não ter entendido seu problema porque concordo que a explanação não é muito clara, insisto: se é para fazer processamento em cima dos dados que chegam, a solução para mim é usar algo como ESPER ou similar (tem um monte, inclusive o da Oracle, que é o da antiga BEA, cujo motor é o ESPER). É por isto que digo que é preciso saber o que se pode rodar na nuvem da Amazon. A solução do tipo CEP costuma consumir muita memória e duvido que faça parte do ambiente de lá.

E a menos que não tenha entendido o rumo da conversa, o armazenamento do tipo chave-valor pode até ser usado como cache mas não é cache. Nunca vi ninguém usar como cache um Redis, MongoDB, CouchDB ou qualquer outro NoSQL (que no fundo é o tal citado Map).

[]s
Luca

Oi Luca, obrigado pelo sua humilde resposta e cooperação!

Bom, seguinte. Acabei de ler algo sobre ESPER… não tenho certeza se eh bem isso que preciso no momento.

Deixe-me tentar ilustrar um pouco melhor. Imagine um serviço que apresenta um sumario do histórico de navegação no site dos parceiros consumidores deste serviço. O javascript vai mandando esses dados para o nosso serviço. De tempos em tempos, em segundo plano, fazermos um apanhado geral dessas informações e geramos esse sumario que eh o resultado do meu pre-processamento. Esse sistema deixa os resultados do processamento armazenado, atualmente em banco de dados mysql.
Dai, a duvida. Sera que não seria melhor armazenar esse resultado de pré-processamento dentro de um bano chave-valor como o os que ja foram mencionados aqui? (Ex.: JDBM, MongoDB, CounchDB e etc). Entenda melhor no sentido de reduzir ao máximo a latência imposta pelo acesso ao banco relacional.

Apesar de meu pouco conhecimento sobre as estrategias de caching, mencionei a questão do dado que envio no header da requisição http pelo fato de que essa informação que eh capaz fazer com que minha aplicação saiba a instancia facade correta, ou seja, esse dado que vai no header eh como se fosse um chave para identificarmos o cliente que esta fazendo a solicitacão e então buscarmos os resultados do pré-processamento no repositório particular do cliente. Hoje temos um schema do mysql diferente para cada cliente. E justamente por essa questão do dado no header eh que eu acho que o caching deve ser afetado, jah que a chave para uma dada resposta no caching eh a url de requisição… atualmente pode ocorrer de existir a mesma url de requisição para o web-service, soh que vindas de clientes diferente… e eu identifico isso pelo dado que estah no header.

PS.: Na verdade nosso serviço beta jah esta funcionando no cloud da Amazon. E acredite… praticamente não ha limitações de ambiente… tenho liberdade total para instalar, configurar e utilizar o que quisermos dentro de cada instancia do cloud.

Muito obrigado pelas opiniões!

Conhece o CouchDB, ele é um banco de dados tipo chave valor, e armazena os dados em formato json que simplifica ao ser consumido via javascript, é um banco de dados altamente escalável, roda sobre HTTP e usa o paradigma funcional, foi desenvolvido usando Erlang.

para saber mais sobre couch e ver uma implementação demo acesse o seguinte site:

http://couchdb.apache.org/

a demo aqui:

http://jan.prima.de/~jan/plok/archives/108-Programming-CouchDB-with-Javascript.html

att. Carlos

Olá

Agora bem mais claro…

O Esper seria útil no caso em que o processamento fosse imediato, isto é, no instante em que as informações chegam e antes de ir para a base de dados. Exemplos: análise de tráfego de rede, transações baseadas em algoritmos, controle de fluxo de veículos, etc.

Gosto muito dos chamados NoSQLs. Para muitas coisas acho melhor do que os bancos de dados tradicionais. Mas não acho que sejam melhores em tudo e que possam eliminar completamente o uso das bases tradicionais. Como já tem um MySQL rodando, o uso de um NoSQL talvez só seja vantajoso nos casos clássicos em que se usa o banco de dados só porque ele está ali (coisas que não fazem parte do negócio como logs e informações de auditoria, sessões de usuário e até mesmo autenticação de usuário). Tudo dependerá de experimentar e medir.

O uso de cache independe do uso de banco de dados. Se ainda não usa, avalie a possibilidade de usar

[]s
Luca

[quote]Conhece o CouchDB, ele é um banco de dados tipo chave valor, e armazena os dados em formato json que simplifica ao ser consumido via javascript, é um banco de dados altamente escalável, roda sobre HTTP e usa o paradigma funcional, foi desenvolvido usando Erlang.

para saber mais sobre couch e ver uma implementação demo acesse o seguinte site:
http://couchdb.apache.org/

a demo aqui:
http://jan.prima.de/~jan/plok/archives/108-Program...g-CouchDB-with-Javascript.html

att. Carlos[/quote]

Carlos, não conhecia essa solução… parece ser muito interessante e realmente aplicável ao cenário! Muito obrigado pela dica!

[quote]
Gosto muito dos chamados NoSQLs. Para muitas coisas acho melhor do que os bancos de dados tradicionais. Mas não acho que sejam melhores em tudo e que possam eliminar completamente o uso das bases tradicionais. Como já tem um MySQL rodando, o uso de um NoSQL talvez só seja vantajoso nos casos clássicos em que se usa o banco de dados só porque ele está ali (coisas que não fazem parte do negócio como logs e informações de auditoria, sessões de usuário e até mesmo autenticação de usuário). Tudo dependerá de experimentar e medir.[/quote]

Luca, como o resultado do pré-processamento, que também compõe a resposta consumida pelo javascript, tem um atributos e formato diferentes do usado no armazenamento primário das informações, acredito que o uso de um banco NoSQL não estaria sendo mal empregado, não acha? Inclusive, aproveitando a ideia do Carlos acima, armazenando no formato JSON já estaria inclusive removendo a camada de parsing (Apache CXF - framework embeded) do objeto java para o formato JSON na hora de responder a solicitação do serviço! Me parece muito interessante essa abordagem! Vou testar!

E quanto ao uso de cache… fato… vou fazer o que você sugere! Alias, já comecei a fazer rs… Tendencioso para o JbossCache que parece ser um pouco mais simples que o conhecido EhCache… Opiniões a respeito?

Estou ficando bastante empolgado com as ideias que vocês estão dando!

Muto obrigado a todos!

Olá

O CouchDB é justamente o que mais conheço. Tem bastante documentação e pelo menos 2 livros publicados sobre ele. Mas há outras opções com melhor performance. A grande vantagem do CouchDB é a facilidade de replicação (herdada do Erlang)

E sobre cache há outras alternativas. Já viu o memcached?

[]s
Luca

Opa!

Luca, se você pudesse mencionar algumas dessas outras opçoes seria interessante!

Um problema que identifiquei com o CouchDB ate o momento:

  • Adição de uma nova layer de rede. Ja que o CouchDB precisa ser instalado como um servidor a parte. E por questoes de segurança, acho que não deve ser seguro eu permitir acesso ao CouchDB através do meu componente javascript… estaríamos expondo nosso banco e as informações core do serviço. Dai, eu vejo que precisaria utilizar um proxy tal comunicação. Minha preocupação eh que isso acabe gerando uma latência no processo. Sera que vale a pena? Acho que eh ai que a estrategia de caching entra neh!?

Parece bem simples também! Vou dar uma boa olhada nesse framework!!!

Olá

[quote=cesarcneto]Um problema que identifiquei com o CouchDB ate o momento:

  • Adição de uma nova layer de rede. Ja que o CouchDB precisa ser instalado como um servidor a parte. E por questoes de segurança, acho que não deve ser seguro eu permitir acesso ao CouchDB através do meu componente javascript… [/quote]

O CouchDB é usado igualzinho a um banco de dados tradicional e é acessado de alguma aplicação que roda no servidor. Ninguém acessaria nenhuma base de dados direto do Javascript. O CouchDB é uma aplicação servidora mas não obrigatoriamente precisa ficar em um servidor a parte. Repito, é apenas outro meio de persistẽncia de dados. Só que orientado a documentos (como um Hash) ao invés de tabelas relacionais.

Não, a opção pelo uso de um NoSQL não tem nada a ver com a opção de usar cache.

Não sei se o memcached pode ser chamado de framework. Não é o mesmo conceito do EhCache ou do JBosscache. Acho que até pode ser usado junto para cachear algumas coisas do site.

E já citei alternativas…

Mais ainda tem outros.

Vá com calma, nada na vida é tão simples que a gente consiga entender com uma simples olhadela.

[]s
Luca