Padrão de transações distribuídas da Saga
O padrão de design saga ajuda a manter a consistência de dados em sistemas distribuídos coordenando transações em vários serviços. Uma saga é uma sequência de transações locais em que cada serviço executa sua operação e inicia a próxima etapa por meio de eventos ou mensagens. Se uma etapa na sequência falhar, a saga executará transações compensatórias para desfazer as etapas concluídas. Essa abordagem ajuda a manter a consistência dos dados.
Contexto e problema
Uma transação representa uma unidade de trabalho, que pode incluir várias operações. Em uma transação, um evento refere-se a uma alteração de estado que afeta uma entidade. Um comando encapsula todas as informações necessárias para executar uma ação ou disparar um evento subsequente.
As transações devem seguir os princípios de atomicidade, consistência, isolamento e durabilidade (ACID).
- Atomicidade: Todas as operações são bem-sucedidas ou nenhuma operação é bem-sucedida.
- Consistência: transições de dados de um estado válido para outro estado válido.
- Isolamento: transações simultâneas produzem os mesmos resultados que transações sequenciais.
- Durabilidade: as alterações persistem após serem confirmadas, mesmo quando ocorrem falhas.
Em um único serviço, as transações seguem os princípios ACID porque operam em um único banco de dados. No entanto, pode ser mais complexo alcançar a conformidade com ACID em vários serviços.
Desafios em arquiteturas de microsserviços
As arquiteturas de microsserviços normalmente atribuem um banco de dados dedicado a cada microsserviço. Essa abordagem oferece vários benefícios:
- Cada serviço encapsula seus próprios dados.
- Cada serviço pode usar a tecnologia de banco de dados e o esquema mais adequados para suas necessidades específicas.
- Os bancos de dados para cada serviço podem ser dimensionados de forma independente.
- Falhas em um serviço são isoladas de outros serviços.
Apesar dessas vantagens, essa arquitetura complica a consistência de dados entre serviços. Garantias de banco de dados tradicionais, como ACID, não são diretamente aplicáveis a vários armazenamentos de dados gerenciados independentemente. Devido a essas limitações, as arquiteturas que dependem da comunicação entre processos ou modelos de transação tradicionais, como o protocolo de confirmação de duas fases, geralmente são mais adequadas para o padrão saga.
Solução
O padrão Saga gerencia transações dividindo-as em uma sequência de transações locais .
Cada transação local:
- Conclui seu trabalho atomicamente em um único serviço.
- Atualiza o banco de dados do serviço.
- Inicia a próxima transação por meio de um evento ou mensagem.
Se uma transação local falhar, a saga executará uma série de transações de compensação para reverter as alterações feitas pelas transações locais anteriores.
Principais conceitos no padrão saga
transações compensadas podem ser desfeitas ou compensadas por outras transações com o efeito oposto. Se uma etapa na saga falhar, a compensação das transações desfazerá as alterações feitas pelas transações compensacionáveis.
transações dinâmicas servem como ponto sem retorno na saga. Depois que uma transação dinâmica for bem-sucedida, as transações compensacionáveis não serão mais relevantes. Todas as ações subsequentes devem ser concluídas para que o sistema alcance um estado final consistente. Uma transação dinâmica pode assumir funções diferentes, dependendo do fluxo da saga:
transações irreversíveis ou não compatíveis não podem ser desfeitas ou repetidas.
O limite entre reversível e confirmado significa que a transação dinâmica pode ser a última transação desfazível ou compensavel. Ou pode ser a primeira operação de repetição na saga.
transações retryable seguir a transação dinâmica. As transações retíveis são idempotentes e ajudam a garantir que a saga possa atingir seu estado final, mesmo que ocorram falhas temporárias. Eles ajudam a saga a alcançar um estado consistente.
Abordagens de implementação de saga
As duas abordagens típicas de implementação da saga são de coreografia e de orquestração. Cada abordagem tem seu próprio conjunto de desafios e tecnologias para coordenar o fluxo de trabalho.
Coreografia
Na abordagem coreográfica, os serviços trocam eventos sem um controlador centralizado. Com a coreografia, cada transação local publica eventos de domínio que disparam transações locais em outros serviços.
Benefícios da coreografia | Desvantagens da coreografia |
---|---|
Bom para fluxos de trabalho simples que têm poucos serviços e não precisam de uma lógica de coordenação. | O fluxo de trabalho pode ser confuso quando você adiciona novas etapas. É difícil rastrear a quais comandos cada participante da saga responde. |
Nenhum outro serviço é necessário para coordenação. | Há um risco de dependência cíclica entre os participantes da saga porque eles têm que consumir os comandos uns dos outros. |
Não introduz um único ponto de falha porque as responsabilidades são distribuídas entre os participantes da saga. | O teste de integração é difícil porque todos os serviços devem ser executados para simular uma transação. |
Orquestração
Na orquestração, um controlador centralizado ou orquestrador, manipula todas as transações e informa aos participantes qual operação executar com base em eventos. O orquestrador executa solicitações de saga, armazena e interpreta os estados de cada tarefa e lida com a recuperação de falhas usando transações de compensação.
Benefícios da orquestração | Desvantagens da orquestração |
---|---|
Mais adequado para fluxos de trabalho complexos ou quando você adiciona novos serviços. | Outra complexidade de design requer uma implementação de uma lógica de coordenação. |
Evita dependências cíclicas porque o orquestrador gerencia o fluxo. | Apresenta um ponto de falha porque o orquestrador gerencia o fluxo de trabalho completo. |
A separação clara de responsabilidades simplifica a lógica do serviço. |
Problemas e considerações
Considere os seguintes pontos ao decidir como implementar esse padrão:
Mudança no pensamento de design: a adoção do padrão saga requer uma mentalidade diferente. Isso exige que você se concentre na coordenação de transações e na consistência de dados em vários microsserviços.
Complexidade das sagas de depuração: sagas de depuração podem ser complexas, especificamente à medida que o número de serviços participantes aumenta.
alterações irreversíveis do banco de dados local: Dados não podem ser revertidos porque os participantes da saga confirmam alterações em seus respectivos bancos de dados.
Tratamento de falhas transitórias e idempotência: O sistema deve lidar com falhas transitórias de forma eficaz e garantir que a idempotência, ao repetir a mesma operação, não altere o resultado. Para obter mais informações, consulte de processamento de mensagens Idempotente.
Necessidade de monitorar e acompanhar sagas: Monitoramento e acompanhamento do fluxo de trabalho de uma saga são tarefas essenciais para manter a supervisão operacional.
Limitações de compensação de transações: as transações de compensação podem nem sempre ter êxito, o que pode deixar o sistema em um estado inconsistente.
Possíveis anomalias de dados em sagas
Anomalias de dados são inconsistências que podem ocorrer quando as sagas operam em vários serviços. Como cada serviço gerencia seus próprios dados, chamados dados de participantes, não há isolamento interno entre os serviços. Essa configuração pode resultar em inconsistências de dados ou problemas de durabilidade, como atualizações parcialmente aplicadas ou conflitos entre serviços. Problemas típicos incluem:
Atualizações perdidas: quando uma saga modifica dados sem considerar as alterações feitas por outra saga, isso resulta em atualizações substituídas ou ausentes.
Dirty lê: Quando uma saga ou transação lê dados que outra saga modificou, mas a modificação não está concluída.
Fuzzy, ou não executável, diz: Quando diferentes etapas em uma saga leem dados inconsistentes porque as atualizações ocorrem entre as leituras.
Estratégias para lidar com anomalias de dados
Para reduzir ou evitar essas anomalias, considere as seguintes contramedidas:
bloqueio semântico: Usar bloqueios no nível do aplicativo quando a transação compensavel de uma saga usa um semáforo para indicar que uma atualização está em andamento.
atualizações comutativas: atualizações de design para que possam ser aplicadas em qualquer ordem enquanto ainda produzem o mesmo resultado. Essa abordagem ajuda a reduzir conflitos entre sagas.
exibição pessimista: reordenar a sequência da saga para que as atualizações de dados ocorram em transações retíveis para eliminar leituras sujas. Caso contrário, uma saga pode ler dados sujos ou alterações não confirmadas, enquanto outra saga executa simultaneamente uma transação compensavel para reverter suas atualizações.
valores de releitura: Confirme se os dados permanecem inalterados antes de você fazer atualizações. Se os dados forem alterados, interrompa a etapa atual e reinicie a saga conforme necessário.
Arquivos de versão: Manter um log de todas as operações executadas em um registro e garantir que elas sejam executadas na sequência correta para evitar conflitos.
simultaneidade baseada em risco com base no valor: escolha dinamicamente o mecanismo de simultaneidade apropriado com base no risco de negócios potencial. Por exemplo, use sagas para atualizações de baixo risco e transações distribuídas para atualizações de alto risco.
Quando usar esse padrão
Use esse padrão quando:
- Você precisa garantir a consistência de dados em um sistema distribuído sem acoplamento apertado.
- Você precisa reverter ou compensar se uma das operações na sequência falhar.
Esse padrão pode não ser adequado quando:
- As transações são firmemente acopladas.
- A compensação de transações ocorre em participantes anteriores.
- Há dependências cíclicas.
Próxima etapa
Recursos relacionados
Os seguintes padrões podem ser relevantes quando você implementa esse padrão:
O padrão coreográfico tem cada componente do sistema participando do processo de tomada de decisão sobre o fluxo de trabalho de uma transação comercial, em vez de depender de um ponto central de controle.
O padrão compensação de transações desfaz o trabalho executado por uma série de etapas e, eventualmente, define uma operação consistente se uma ou mais etapas falharem. Aplicativos hospedados na nuvem que implementam processos de negócios complexos e fluxos de trabalho geralmente seguem esse modelo de consistência eventual.
O padrão de repetição permite que um aplicativo trate falhas transitórias quando tenta se conectar a um serviço ou recurso de rede repetindo de forma transparente a operação com falha. Esse padrão pode melhorar a estabilidade do aplicativo.
O padrão Disjuntor lida com falhas que levam um tempo variável para se recuperar quando você se conecta a um serviço ou recurso remoto. Esse padrão pode melhorar a estabilidade e a resiliência de um aplicativo.
O padrão Monitoramento de Ponto de Extremidade de Integridade implementa verificações funcionais em um aplicativo que as ferramentas externas podem acessar por meio de pontos de extremidade expostos em intervalos regulares. Esse padrão pode ajudá-lo a verificar se os aplicativos e serviços estão sendo executados corretamente.