Sugestões de mensageria ou distribuição de processamento.  XML
Índice dos Fóruns » Outras Linguagens
Autor Mensagem
peczenyj
Moderador
[Avatar]

Membro desde: 26/03/2006 23:25:37
Mensagens: 3191
Localização: Rio de Janeiro
Offline

Ola

Hoje eu trabalho com um sistema bem simples (hoje perl, sendo reescrito em ruby). Dado um input de um usuário eu crio um arquivo em um diretório X (cujo nome é um "UUID" dessa requisição) e esse diretório é processado por vários módulos.

Cada modulo é um serviço que fica olhando para um diretorio (indir) e, quando chega alguma coisa, move pra um 'workdir' e, terminado o processamento, move para um 'outdir' que pode ser o indir do proximo módulo.

É uma fila implementada em um filesystem, basicamente, "controlado" por um modulo central via pequenas requisições a uma api REST. O sistema é muito simples (e robusto) porém é fortemente baseado em I/O e funciona redondo para sistemas sequenciais onde tenho que fazer os processamentos A -> B -> C -> ...Z .

Eu não queria perder a simplicidade mas existe um requisito de paralelizar algumas operações em maquinas distintas e ai fazer fila em filesystem se torna um inferno, pois tenho montagem NFS e minhas operações de movimentação deixam de ser atômicas, por exemplo. Nesse caso eu quero passar para algo como

A -> ( B, C , D ) -> E

onde o que esta entre parentesis deve ser feito em paralelo - em maquinas fisicas diferentes. Tenho outro requisito que é lidar com prioridade de fila, que hoje é complicado pois cada modulo funciona "quando pode".

Pergunta:
Existe alguma coisa que seja simples (no sentido de ter poucas dependências, para ter poucos pontos de falha) de implementar que me dê estas caracteristicas? Pensei em SOAP sobre XMPP ao invés de criar algo em um diretório mas não sei se existe algo mais simples.

Talvez alguma mensageria de forma mais leve, não sei. Aceito sugestões.

http://pacman.blog.br

'Não importa quanto alguém se dedique à tarefa. Ninguém consegue fazer a água da cascata cair para cima.'
[WWW]
Bruno Laturner
GUJ Expert
[Avatar]

Membro desde: 18/02/2008 16:17:53
Mensagens: 3002
Offline

Bem, tens um sistema simples e robusto, quer paralelizar partes deles, e ainda manter a nova implementação com poucas dependências, e ainda super simples. Vou tentar trabalhar com o que já existe:

Esse compatilhamente via NFS realmente está te atrapalhando? Não funciona em paralelo ou é somente uma suposição? Eu sei que pode acontecer de dois serviços lerem o mesmo arquivo ao mesmo tempo, mas acontece ao tirar o arquivo de um lugar e mover para outro? O proprio sistema operacional deveria tratar dessa movimentação atômicamente.

Outra pergunta, A -> ( B, C , D ) -> E significa

A -> ( B -> C -> D) -> E , em parenteses sendo a operação sendo executada em paralelo ou
A -> (B) -> E, A -> (C) -> E, A -> (D) -> E, ou uma mistura disto?


Possivel solução:

Se não puder fazer com que a máquina 2 pegue os arquivos diretamente do indir1 remoto e coloque no workdir2 local, que tal a máquina 2 pedir para a máquina 1 colocar o arquivo lá? Seria uma inversão do controle da movimentação dos arquivos, onde a máquina 1 teria uma fila interna(muito simples, sem recorrer a mensageria) para atender os pedidos.

A resposta acima foi achada em menos de 5 minutos no google.
The prisoner falls in love with his chains. --E.W. Dijkstra
[WWW]
mochuara
GUJ Master
[Avatar]
Membro desde: 20/05/2009 11:21:32
Mensagens: 1776
Offline

Voce diz que o requisito é distribuir o processamento para diferentes máquinas. Mas eu duvido muito que esse seja o requisito, acho que o verdadeiro requisito vc omitiu da gente. Algo como fazer o serviço mais rápido, ou ser tolerante a piques de luz na maquina responsavel pelo processamento, etc.

Se realmente a arquitetura precisa passar a ser distribuida e o filesystem realmente não der conta vc pode adotar uma arquitetura de queue distribuída, como isso: http://aws.amazon.com/sqs/

This message was edited 1 time. Last update was at 12/04/2010 15:53:16

mochuara
GUJ Master
[Avatar]
Membro desde: 20/05/2009 11:21:32
Mensagens: 1776
Offline

Simples e distribuído simplesmente não existe.
peczenyj
Moderador
[Avatar]

Membro desde: 26/03/2006 23:25:37
Mensagens: 3191
Localização: Rio de Janeiro
Offline

ok, tenho uma exigencia de SLA de alguns minutos

ao inves de fazer

a -> b -> c -> d

onde b e c demoram muito mas são independentes eu gostaria de fazer

a -> ( maquina x faz b; maquina y faz c) -> d

na melhor das hipoteses eu tenho o tempo total como sendo

t_a + max(t_b,t_c) + t_d

http://pacman.blog.br

'Não importa quanto alguém se dedique à tarefa. Ninguém consegue fazer a água da cascata cair para cima.'
[WWW]
Kenobi
GUJ Master
[Avatar]

Membro desde: 14/11/2003 13:06:37
Mensagens: 1678
Localização: Brasil
Offline

Olá Tiago, desculpe-me a demora na resposta, mas estava esperando o pessoal postar suas soluções .

Bom, na minha ótica BPEL seria o melhor candidato pra resolver seu problema, em que você tivesse que quebrar a cabeça com nada. Poderia manter a implementação do seu projeto em Ruby e "Orquestrar" as chamadas e recursos diramente da engine.

Algumas implementações como o produto da Oracle, possuem até adaptadores à arquivos (FileAdapter), Queue e DB, então ficaria bem suave.

Dê uma olhada no exemplo a seguir de como seria uma solução desse tipo - http://blogs.sun.com/malkit/entry/dynamic_services_composition_in_bpel

Parece complexo, mas um profissional com um pouco de experiência monta uma solução dessa em uma tarde.

Aliás, daria pra você usar uma Engine dessas e usar uma implementação de WS-Ruby como da WSo2 que suporta o que você precisaria:

- SOAP MTOM
- WS-Addressing
- WS-Security
- WS-SecurityPolicy
- WS-ReliableMessaging

http://wso2.org/project/wsf/ruby/1.1.0/docs/index.html e faria somente a coordenação no BPEL.

Voltando ao mundo Ruby, o buraco vai ser mais embaixo, exatamente por que coisas que a especificação WS* cuida pra você, como WS-Coordination, você terá que fará na mão, montando um monitor, compensação, para casos de falha e por aí vai.


Distribuir o processamento, vai exigir um framework pra vc montar suas queues, diria que pode usar o Starling, ActiveMessaging ou até mesmo JMS se tiver usando JRuby em cima de um ApplicationServer - dica, use o framework do Leandro Silva (codezone) http://github.com/leandrosilva/jsparrow

Uma das maneiras de garantir a atomicidade é utilizar um cache e também de ter um pouco mais de segurança no seu processamento, já que este pode ser distribuído, então utilize algo como Redis.

De qualquer maneira terá que construir um monitor e cobrir as falhas, compensação dependendo da sua regra de negócio.

Aqui tem um projetinho, Resque do pessoal do Redis para você se inspirar : http://github.com/defunkt/resque

Por fim, a última abordagem que vem à minha cabeça é utilizar um STM Framework (http://en.wikipedia.org/wiki/Software_Transactional_Memory) para garantir a atomicidade da operação. Essa idéia é originária do Clojure, mas descobri isso num framework Scala chamado Akka - http://akkasource.org.

Aliás seria bacana se tivesse algo assim pro mundo Ruby - http://doc.akkasource.org/stm , mas não achei nada concreto, o mais perto foi esse blog: http://moonbase.rydia.net/mental/blog/programming/ruby-stm-first-round.html

PS: Acredito que você entende por mais simples, pode nesse caso consumir um bom tempo de desenvolvimento e "quebra" cabeça


Depois poste sua solução, estou curioso pra saber como resolveu

This message was edited 10 times. Last update was at 14/04/2010 17:36:52


----------------------------------------------------------
SOA|EXPERT - http://www.soaexpert.com.br
SOA de um jeito simples e eficiente.
[WWW] [MSN] [ICQ]
mochuara
GUJ Master
[Avatar]
Membro desde: 20/05/2009 11:21:32
Mensagens: 1776
Offline

peczenyj wrote:ok, tenho uma exigencia de SLA de alguns minutos

ao inves de fazer

a -> b -> c -> d

onde b e c demoram muito mas são independentes eu gostaria de fazer

a -> ( maquina x faz b; maquina y faz c) -> d

na melhor das hipoteses eu tenho o tempo total como sendo

t_a + max(t_b,t_c) + t_d


Sei que Ruby não tem threads, mas se vc arrumasse uma maneira de disparar b e c para rodar como processos na mesma máquina "simultaneamente", ao inves de sequencialmente, não conseguiria atender as exigencias do SLA?

This message was edited 1 time. Last update was at 13/04/2010 09:42:08

andre_salvati
GUJ Ranger

Membro desde: 02/06/2005 16:28:38
Mensagens: 939
Offline

Processamento batch?

Quartz. O Spring tem um módulo para ajudar na implementação com Quartz.

Ajude na criação do StackOverflow em português!!!

http://area51.stackexchange.com/proposals/23539/software-development-in-portuguese?referrer=tI8Uon7RDszY236h5e0UuA2


http://www.empresadigital.inf.br
http://twitter.com/afsalvati
Kenobi
GUJ Master
[Avatar]

Membro desde: 14/11/2003 13:06:37
Mensagens: 1678
Localização: Brasil
Offline

andre_salvati wrote:Processamento batch?

Quartz. O Spring tem um módulo para ajudar na implementação com Quartz.


Olá André, se for batch com Spring, usa logo o SpringBatch http://static.springsource.org/spring-batch/

This message was edited 1 time. Last update was at 13/04/2010 14:10:03


----------------------------------------------------------
SOA|EXPERT - http://www.soaexpert.com.br
SOA de um jeito simples e eficiente.
[WWW] [MSN] [ICQ]
Luca
Moderador
[Avatar]

Membro desde: 06/09/2002 14:30:10
Mensagens: 5810
Localização: São Paulo/SP ou Paraty/RJ
Offline

Olá

Não sei se entendi bem. Mas me veio a cabeça a idéia de você abandonar completamente o file system e armazenar as coisa em um CouchDb eventualmente replicado.

Não consegui achar nenhuma outra idéia mantendo o uso do file system (que realmente é bem simples [*])

[*] O uso de file system para trocar informações entre sistemas heterogêneos é o que sempre usaram os programadores mais ágeis que nunca quiseram se meter com idéias toscas como CORBA, RPC e outras coisas desnecessariamente complicadas e às vezes dependentes de intermediação paga.

[]s
Luca

Dare Obasanjo (Program Manager at Microsoft)
"The folks I know from across the industry who have to build large scale Web services on the Web today at Google, Yahoo!, Facebook, Windows Live, Amazon, etc are using RESTful Web services. The only times I encounter someone with good things to say about WS-* is if it is their job to pimp these technologies or they have already "invested" in WS-* and want to defend that investment."


CEP, JMS, JMX e coisas afins (ou não)
http://lucabastos.blogspot.com/
[Email] [WWW]
Kenobi
GUJ Master
[Avatar]

Membro desde: 14/11/2003 13:06:37
Mensagens: 1678
Localização: Brasil
Offline

Olá Luca, exatamente minha sugestão só que usando o Redis.

Vi uma excelente apresentação no GuruSP (Felipe Vieira) sobre o case do Boo-box e chegaram usar CouchDB. O ganho que tiveram com o Redis foi enorme, acredito ser um produto mais maduro. Melhor otimização de memória (muito mesmo) e performance em menos de 3% do servidor, contra uns 50% do CouchDB.

Outra coisa que o Redis tem um mencanismo de persistência em filesystem, caso ele precise.(ainda em beta) -http://code.google.com/p/redis/wiki/Features


----------------------------------------------------------
SOA|EXPERT - http://www.soaexpert.com.br
SOA de um jeito simples e eficiente.
[WWW] [MSN] [ICQ]
Luca
Moderador
[Avatar]

Membro desde: 06/09/2002 14:30:10
Mensagens: 5810
Localização: São Paulo/SP ou Paraty/RJ
Offline

Olá

Kenobi wrote:Vi uma excelente apresentação no GuruSP (Felipe Vieira) sobre o case do Boo-box e chegaram usar CouchDB. O ganho que tiveram com o Redis foi enorme, acredito ser um produto mais maduro. Melhor otimização de memória (muito mesmo) e performance em menos de 3% do servidor, contra uns 50% do CouchDB.


Pena, perdi esta. Tinha entendido sua sugestão como se fosse apenas para cache.

Adoro soluções simples como esta de usar o file system. Já usei muito para integrar VB com Java, Delphi com Java, C com Java e até mesmo C com C em uma aplicação dividida em 4 módulos diferentes.

Uma idéia que me ocorreu agora mas que pode ser puro devaneio é o uso de SkipLists para controlar as concurrent priority queues. Para isto eu usaria Java e JRuby. Pode ser que esteja viajando mas que ficaria bunitinho não tenho dúvidas.

[]s
Luca

Dare Obasanjo (Program Manager at Microsoft)
"The folks I know from across the industry who have to build large scale Web services on the Web today at Google, Yahoo!, Facebook, Windows Live, Amazon, etc are using RESTful Web services. The only times I encounter someone with good things to say about WS-* is if it is their job to pimp these technologies or they have already "invested" in WS-* and want to defend that investment."


CEP, JMS, JMX e coisas afins (ou não)
http://lucabastos.blogspot.com/
[Email] [WWW]
Kenobi
GUJ Master
[Avatar]

Membro desde: 14/11/2003 13:06:37
Mensagens: 1678
Localização: Brasil
Offline

Luca wrote:Olá

Não sei se entendi bem. Mas me veio a cabeça a idéia de você abandonar completamente o file system e armazenar as coisa em um CouchDb eventualmente replicado.

Não consegui achar nenhuma outra idéia mantendo o uso do file system (que realmente é bem simples [*])

[*] O uso de file system para trocar informações entre sistemas heterogêneos é o que sempre usaram os programadores mais ágeis que nunca quiseram se meter com idéias toscas como CORBA, RPC e outras coisas desnecessariamente complicadas e às vezes dependentes de intermediação paga.

[]s
Luca


Luca só um detalhe da sua afirmação quanto à CORBA e RPC, em muitos cenários havia a necessidade da operação ser online e na época ou era isso ou solução proprietária como Tuxedo.

----------------------------------------------------------
SOA|EXPERT - http://www.soaexpert.com.br
SOA de um jeito simples e eficiente.
[WWW] [MSN] [ICQ]
Luca
Moderador
[Avatar]

Membro desde: 06/09/2002 14:30:10
Mensagens: 5810
Localização: São Paulo/SP ou Paraty/RJ
Offline

Olá

Kenobi wrote:... só um detalhe da sua afirmação quanto à CORBA e RPC, em muitos cenários havia a necessidade da operação ser online e na época ou era isso ou solução proprietária como Tuxedo.


A necessidade de ser on line não justifica o acoplamento (a palavra mais adequada é engrunvinhamento porque é mais feia e assim descreve melhor como ficam os sistemas).

Cansei de usar troca de arquivos para comunicar sistemas de cartão de crédito que precisam responder ao cliente lá na ponta em poucos segundos. Como era simples, funcionava rápido. Quando por outras exigências trocamos isto em um sistema para usar sockets, levamos um bom tempo apanhando dos erros de rede até que os dois sistemas conseguissem falar o mesmo ISO 8583.

Nunca vi nada que justificasse o uso de CORBA, DCOM e outros complicômetros. Foi um modismo idiota de um tempo em que os "especialistas", isto é, vendedores de ORBs, tentavam convencer o mundo que integração precisava de RPC. Para usar estas porcarias ambos os sistemas precisavam de modificações grandes e complexas.

Só para depurar estes monstrengos era preciso de gente muito qualificada.

Veja abaixo como ficaria simples e desacoplado (tirado do livro Camel in Action usando Apache Camel) para fazer polling em um diretório inbox checando de tempos em tempos se chegou alguma coisa e em caso afirmativo rotear para um diretório outbox. Isto é o mais básico exemplo de troca de mensagem que consigo imaginar. Mas não está muito diferente do que era feito nos tempos em que trabalhei com cartão de crédito.



[]s
Luca

Dare Obasanjo (Program Manager at Microsoft)
"The folks I know from across the industry who have to build large scale Web services on the Web today at Google, Yahoo!, Facebook, Windows Live, Amazon, etc are using RESTful Web services. The only times I encounter someone with good things to say about WS-* is if it is their job to pimp these technologies or they have already "invested" in WS-* and want to defend that investment."


CEP, JMS, JMX e coisas afins (ou não)
http://lucabastos.blogspot.com/
[Email] [WWW]
peczenyj
Moderador
[Avatar]

Membro desde: 26/03/2006 23:25:37
Mensagens: 3191
Localização: Rio de Janeiro
Offline

mochuara wrote:Sei que Ruby não tem threads, mas se vc arrumasse uma maneira de disparar b e c para rodar como processos na mesma máquina "simultaneamente", ao inves de sequencialmente, não conseguiria atender as exigencias do SLA?


O problema não são threads, são 3 processamentos (atualmente) que são muito pesados e ocupam todas os cores de cpu possiveis, 2 deles são encoding de video usando ffmpeg e 1 deles usa ImageMagick (que comparado com o ffmpeg é até leve).

Estou inclinado a resolver da seguinte forma

Quando precisar fazer:
Inicio -> [B,C,D] -> Fim

Eu faço

Inicio -> X - > Fim

onde X é um processo que orquestra 3 processos em servidores distribuidos, dedicados a este processamento.

Nesse caso eu separo o refactoring em 2 partes

1) Distribuo apenas o processamento "especial" e atendo o meu problema, reduzindo o escopo.
2) Transformo o meu sistema em outra coisa, talvez até com outra tecnologia (Scala ??)

Se eu reduzir escopo ao que eu realmente quero, que é rodar 3 processos em paralelo em 3 maquinas diferentes, tenho espaço para experimentar tecnologias (como couchDB distribuido, BPEL) e mantenho um plano B que seria voltar ao processo sincrono em uma emergência.

Como o processo que trabalha com encoding de video é o mais pesado, vou começar por eles, assim que reler as sugestões do Kenobi & cia

This message was edited 1 time. Last update was at 14/04/2010 17:43:29


http://pacman.blog.br

'Não importa quanto alguém se dedique à tarefa. Ninguém consegue fazer a água da cascata cair para cima.'
[WWW]
 
Índice dos Fóruns » Outras Linguagens
Ir para:   
Powered by JForum 2.1.8 © JForum Team