Transações e filas distribuídas, ruby, erlang

5

Eu tenho um problema que envolve várias máquinas, filas de mensagens e transações. Por exemplo, quando um usuário clica em uma página da Web, o clique envia uma mensagem para outra máquina que adiciona um pagamento à conta do usuário. Pode haver muitos milhares de cliques por segundo. Todos os aspectos da transação devem ser tolerantes a falhas.

Eu nunca tive que lidar com algo assim antes, mas um pouco de leitura sugere que este é um problema bem conhecido.

Então, para minhas perguntas. Estou correto em assumir que a maneira segura de fazer isso é com um commit de duas fases, mas o protocolo está bloqueando e, portanto, não obtenho o desempenho necessário? Parece que os bancos de dados como redis e sistema de enfileiramento de mensagens como Rescue, RabbitMQ etc. realmente não me ajudam muito - mesmo se implementar algum tipo de commit de duas fases, os dados serão perdidos se o redis falhar porque é essencialmente apenas memória .

Tudo isso me levou a olhar erlang - mas antes de entrar e começar a aprender um novo idioma, eu realmente gostaria de entender melhor se isso valer o esforço. Especificamente, estou certo em pensar que, devido às suas capacidades de processamento paralelo, o erlang é a melhor opção para implementar um protocolo de bloqueio como o commit de duas fases, ou estou confuso?

    
por chrispanda 13.10.2011 / 09:13
fonte

3 respostas

1

Com base no comentário, você não tem um commit de duas fases. Você tem dois problemas normais de confirmação de uma fase.

Uma solução simples (mas provavelmente errada) seria ter o site, quando clicado, inserir um registro no banco de dados. Isso pode ser feito transacionalmente durante o processamento da Web, portanto, há uma alta probabilidade de que o usuário saiba que o clique foi feito. Mas nesse ponto eles não saberão que o pagamento foi feito.

Um sistema separado poderia pesquisar o banco de dados (eu disse que provavelmente estava errado) procurando por entradas. Se encontrar uma entrada, ela poderá excluir essa linha de forma transacional e alterar o registro de pagamento. Isso cria um sistema reinicializável simples.

Se você quer que ele seja um pouco mais em tempo real, você pode usar uma fila, com semântica de transação em ambas as extremidades, e uma fila durável (ou seja, baseada em disco) no meio.

O clique da Web faria com que algo fosse enfileirado de forma transacional. O gerenciador de filas cuidaria de persistir no disco se isso for apropriado. No final do pagamento, é possível remover o arquivamento de um item e registrar o pagamento. Nenhum commit de duas fases é necessário (mais ou menos) porque você nunca está realmente lidando com recursos distribuídos. Se o seu servidor de enfileiramento falhou, você deve de alguma forma ser capaz de detectar se o item mais recente na fila já está no banco de dados, mas isso deve ser resolvido com algum tipo de ID de solicitação na mensagem.

A menos que eu tenha entendido a questão completamente errado. Como não entendo quais são os dois recursos que você está tentando fazer o commit de duas fases entre ...

    
por 14.10.2011 / 21:09
fonte
1

Eu usei o Redis com filas de mensagens para um pequeno sistema distribuído de 24 nós. É muito bom, de alto desempenho e fácil de usar, com muitas ligações de idioma. Eu uso com Python e PHP. Ele também possui um recurso que serializa cada operação para o disco e, no caso de falta de energia, você pode reproduzir o log. Talvez você possa tentar prototipar uma solução para o seu problema e ver se ele faz o trabalho. A curva de aprendizado não é tão íngreme quanto Erlang. : -)

    
por 20.01.2012 / 14:42
fonte
0

Contanto que o middleware da sua fila de mensagens seja reinicializável e possa garantir o processamento Exatamente Uma vez, você estará bem. Seus aplicativos devem deixar suas solicitações na fila, e a ferramenta de middleware cuidará de persistir isso e gerenciar a atividade de repetição. No final da "camada de dados", você precisa apenas certificar-se de que sua transação para o banco de dados e sua confirmação para o middleware ocorra corretamente.

Isso pode ser tratado por uma ferramenta de confirmação de fase XA 2 adequada, ou você pode contorná-la.

Por exemplo, talvez, salve o ID da mensagem exclusiva no banco de dados ao registrar o pagamento e, antes de fazer um pagamento, verifique se o ID da mensagem exclusiva não foi visto antes.

    
por 06.01.2012 / 12:05
fonte