Editar

Compartilhar via


Padrão de transações distribuídas da Saga

Azure

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á a compensação de transações para desfazer as etapas concluídas, mantendo 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 têm êxito ou nenhuma.
  • de consistência: os dados fazem a transição de um estado válido para outro.
  • isolamento: transações simultâneas produzem os mesmos resultados que as sequenciais.
  • durabilidade: uma vez confirmadas, as alterações persistem mesmo em falhas.

Em um único serviço, as transações seguem os princípios ACID porque operam em um único banco de dados. No entanto, alcançar a conformidade acid em vários serviços é mais complexo.

Desafios em arquiteturas de microsserviços

As arquiteturas de microsserviços normalmente atribuem um banco de dados dedicado a cadade microsserviço, que 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.
  • Dimensionamento independente de bancos de dados para cada serviço.
  • Falhas em um serviço são isoladas de outras.

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, arquiteturas que dependem de IPC (comunicação entre processos) ou modelos de transação tradicionais, como o protocolo de confirmação de duas fases (2PC), 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 (ver a figura 1).

Diagrama que mostra uma visão geral da saga.
Figura 1. Uma saga com três serviços.

Cada transação local:

  1. Conclui seu trabalho atomicamente em um único serviço.
  2. Atualiza o banco de dados do serviço.
  3. Inicia a próxima transação por meio de um evento ou mensagem.
  4. 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 compensacionáveis: transações que outras transações podem desfazer ou compensar 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.

  • de transação dinâmica: a transação dinâmica serve como o "ponto sem retorno" na saga. Depois que a transação dinâmica for bem-sucedida, as transações compensacionáveis (que podem ser desfeitas) 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 se enquadrar em funções diferentes dependendo do fluxo da saga:

    • irreversível (não compatível): não pode ser desfeito ou repetido.

    • Limite entrereversível e confirmado: pode ser a última transação desabilitável (compensavel) ou pode ser a primeira operação retível na saga.

  • transações retryable: essas transações seguem a transação dinâmica. As transações retíveis são idempotentes e garantem que a saga possa atingir seu estado final, mesmo que ocorram falhas temporárias. Ele garante que a saga alcance um estado consistente eventualmente.

Abordagens de implementação de saga

Há duas abordagens comuns de implementação de saga, 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 coreografia, 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 (ver a figura 2).

Diagrama que mostra uma saga usando a coreografia.
Figura 2. Uma saga que usa a coreografia.

Benefícios da coreográfica desvantagens do coreográfico
Bom para fluxos de trabalho simples com poucos serviços e não precisa de uma lógica de coordenação. O fluxo de trabalho pode ficar confuso ao adicionar novas etapas. É difícil rastrear quais participantes da saga ouvem quais comandos.
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, pois as responsabilidades são distribuídas entre os participantes da saga. O teste de integração é difícil porque todos os serviços devem estar em execução para simular uma transação.

Orquestração

Na orquestração, um controlador centralizado (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 com transações compensatórias (ver a figura 3).

Diagrama que mostra uma saga usando orquestração.
Figura 3. Uma saga que usa orquestração.

benefícios do de orquestração desvantagens do de orquestração
Mais adequado para fluxos de trabalho complexos ou ao adicionar novos serviços. Outra complexidade de design requer uma implementação de uma lógica de coordenação.
Evita dependências cíclicas, pois 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 implementar o padrão saga:

  • Mudança no pensamento de design: a adoção do padrão saga requer uma mentalidade diferente, concentrando-se na coordenação de transações e na garantia da consistência de dados em vários microsserviços.

  • Complexidade das sagas de depuração: as sagas de depuração podem ser complexas, especialmente à medida que o número de serviços participantes aumenta.

  • alterações irreversíveis do banco de dados local: os 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 efetivamente e garantir a idempotência, em que repetir a mesma operação não altera o resultado. Para obter mais informações, consulte de processamento de mensagens Idempotente.

  • necessidade de monitorar e acompanhar sagas: o monitoramento e o acompanhamento do fluxo de trabalho de uma saga são essenciais para manter a supervisão operacional.

  • Limitações de compensação de transações: a compensação de transações pode nem sempre ter êxito, potencialmente deixando o sistema em um estado inconsistente.

Possíveis anomalias de dados em sagas

Anomalias de dados são inconsistências que podem ocorrer quando sagas são executadas em vários serviços. Como cada serviço gerencia seus próprios dados (dados de participante), 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. Os problemas comuns incluem:

  • atualizações perdidas: quando uma saga modifica dados sem considerar as alterações feitas por outra saga, ela leva a atualizações substituídas ou ausentes.

  • Dirty lê: quando uma saga ou transação lê dados que outra saga modificou, mas ainda não foi concluída.

  • Difuso (não legível) lê: quando diferentes etapas em uma saga leem dados inconsistentes porque ocorrem atualizações entre as leituras.

Estratégias para lidar com anomalias de dados

Para reduzir ou prevenir essas anomalias, considere estas contramedidas:

  • de bloqueio semântico: use bloqueios no nível do aplicativo em que a transação compensavel de uma saga usa um semáforo para indicar que uma atualização está em andamento.

  • atualizações comutativas: criar atualizações para que possam ser aplicadas em qualquer ordem enquanto ainda produzem o mesmo resultado, reduzindo conflitos entre sagas.

  • exibição pessimista: reordene 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 poderia ler dados sujos (alterações não confirmadas), enquanto outra saga executa simultaneamente uma transação compensavel para reverter suas atualizações.

  • releitura de valores: valide se os dados permanecem inalterados antes de fazer atualizações. Se os dados forem alterados, anule a etapa atual e reinicie a saga conforme necessário.

  • arquivos de versão: mantenha um log de todas as operações em um registro e verifique se eles são executados na sequência correta para evitar conflitos.

  • simultaneidade baseada em risco (por 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 as de alto risco.

Quando usar esse padrão

Use o padrão saga quando precisar:

  • Verifique a consistência de dados em um sistema distribuído sem acoplamento apertado.
  • Reverta ou compense se uma das operações na sequência falhar.

O padrão saga é menos adequado para:

  • Transações firmemente acopladas.
  • Compensando transações que ocorrem em participantes anteriores.
  • Dependências cíclicas.

Próximas etapas

  • de dados distribuídos
  • Richardson, Chris. 2018: padrões de microsserviços . Manning Publications.

Os seguintes padrões também podem ser úteis ao implementar esse padrão:

  • Coreografia tem cada componente do sistema participando do processo de tomada de decisão sobre o fluxo de trabalho de uma transação de negócios, em vez de depender de um ponto central de controle.
  • compensação de transações desfazer o trabalho executado por uma série de etapas e, eventualmente, definir 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.
  • 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. A repetição pode melhorar a estabilidade do aplicativo.
  • Disjuntor lida com falhas que levam um tempo variável para se recuperar ao se conectar a um serviço ou recurso remoto. O disjuntor pode melhorar a estabilidade e a resiliência de um aplicativo.
  • 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. O monitoramento de ponto de extremidade de integridade pode ajudar a verificar se os aplicativos e serviços estão sendo executados corretamente.