Escalando sistemas com soluções NoSQL
Postado em 07. jun, 2010 por douglas.campos em Arquitetura
Um dos grandes desafios enfrentados no dia a dia do desenvolvedor eficaz é o de cumprir requisitos não-funcionais de uma aplicação, principalmente os relacionados a performance e escalabilidade. Uma das alternativas mais conhecidas para escalar horizontalmente é a de dividir as tarefas que não necessitam de retorno imediato ao cliente em processos batch. Para tanto, podemos usar diversas ferramentas, desde soluções caseiras até diversos frameworks, tanto em ruby como em java.
Quando se trata de processos batch, é comum buscar um controle mais fino sobre o resultado da execução (sucesso, falha, pendente, etc). Normalmente, usaríamos bancos relacionais para isso, tanto pela sua popularidade como pela performance. Supondo que eu precise gerenciar 1000 pequenas tarefas simultâneas, pagaríamos um preço bem alto pela concorrência, visto que o banco começaria a demorar para obter o lock, fazer o insert, refazer o lock e atualizar o status da tarefa. Muitos consideram o uso de banco de dados relacionais um erro para casos como esse. Buscando eficiência, poderíamos usar uma solução NoSQL para persistência e controle das tarefas, onde evitaríamos os locks, graças ao modelo de concorrência simplificado.

Uma opção em ruby é o resque, um framework de processamento batch criado pelo github que utiliza o redis, um banco de dados não-relacional, tanto para persistir as tarefas, como para coordenar os diversos processos executores de tarefas, mais conhecidos como workers.
Agendar um processo é bem simples – basta que eu tenha uma classe ruby com um método perform, com o processamento a ser executado e um atributo de instância @queue define em qual fila a tarefa será colocada:
# uma classe qualquer, poderia ser um model
class Relatorio
@queue = :relatorio_anual
def self.perform(ano)
gera_relatorio_anual(ano)
end
end
e finalmente, faço o agendamento:
#método recebe a classe da tarefa, e os argumentos Resque.enqueue(Relatorio, 2009)
Essa chamada faz uso bem eficiente de metaprogramação, de maneira que um worker posteriormente executará um código semelhante a esse:
classe, argumentos = Resque.reserve(:relatorio_anual) classe.perform(*argumentos) if class.respond_to? :perform
posteriormente iniciamos um worker usando as tasks do rake que vem no próprio resque, indicando qual fila o worker que estamos criando vai atender
$ QUEUE=relatorio_anual rake resque:work
assim que o worker subir ele já irá executar Resque.reserve, que o colocará em espera por novos trabalhos. opcionalmente, poderíamos executar um worker para atender todas as filas:
$ QUEUE=* rake resque:work
O principal fator que contribui para que resque e redis funcionem como um relógio é o fato de ambos estarem focados em alta performance e, ao mesmo tempo, extrema simplicidade sem ser muito invasivo, já que permitem que você mantenha sua estrutura de persistência relacional inalterada.
Cada vez mais sistemas vem utilizando solucões NoSQL para algumas funcionalidades específicas, como foi o caso recente do Large Hadron Collider com o Mongo DB. Parece que a combinação de bancos relacionais e não-relacionais no mesmo sistema, cada um com seu propósito, tem sido a direção tomada pelo mercado.
10 Respostas para “Escalando sistemas com soluções NoSQL”
Trackbacks/Pingbacks
-
-
agosto 23, 2010
[...] escalabilidade é afetada pois compartilhar recursos em memória na camada web, entre eles dados cacheados do banco ou filas, permitem diminuir o tempo de processamento ou de latência, aumentando o número de requisições [...]
-
-
fevereiro 9, 2011
[...] escalar a leitura não aumenta necessariamente a performance percebida pela API: a query pode continuar lenta, mas mais queries podem rodar concorrentemente. Por outro lado, [...]
ASSINE NOSSO RSS




lucas stephanou
07. jun, 2010
esse cara ma pareceu extremanente perfomatico.
mas e na questao de confiabilidade?
entre usar ele ou uma solucao propria com rabbitmq?
douglas.campos
07. jun, 2010
@lucas
Realmente, o resque é muito rápido, fiz alguns “benchmarks caseiros”, onde ele se comportou muito bem. Quanto à confiabilidade e a viabilidade de usá-lo, como quase toda solução arquitetural, depende da avaliação de vários fatores do seu sistema, equipe e processos da empresa, e de uma boa bateria de testes durante uma prova de conceito.
lucas stephanou
08. jun, 2010
@douglas.campos sem duvida, neste momento é o que tenho feitos. Testes com infinitas soluçoes.
Como tu bem pontuou, é arquitetura, e como tal tem muitas soluçoes, e é sempre bom ler sobre a experiencia alheia.
Antonio Kantek
08. jun, 2010
Na minha opiniao, o JavaSpace pode ser considerado um banco de dados tipo NoSQL. Acho que o model mestre/escravo (ahahah gostaram dessa) se encaixa perfeito nesse exemplo.
Marcio Duran
09. jun, 2010
O assunto NoSQL é interessante, pode também ser consultado no IBM DeveloperWork.
Fonte abaixo:
http://www.ibm.com/developerworks/br/java/library/j-javadev2-8/index.html?ca=drs-
Otavio Angel Silva
11. jun, 2010
resque bom valeu
Arvin
16. jun, 2010
Legal Douglas.
Qual seria uma boa opção Java?
Symon
16. jun, 2010
Tem algo parecido com isso em Java?
Eu já havia imaginado algo parecido com isso: criei uma classe chamada TaskXYZ que herdava de Task e tinha um método execute() – tipo um command.
Dai você pode mandar isso pra uma fila, persistir, recuperar em caso de desligamento do equipamento, e processar a fila denovo. Lindo isso.