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

Azure

O padrão de design da Saga é uma forma de gerir a consistência dos dados em microserviços em cenários de transação distribuídos. Uma saga é uma sequência de transações que atualiza cada serviço e publica uma mensagem ou evento para desencadear o próximo passo de transação. Se um passo falhar, a saga executa transações compensatórias que contrariam as transações anteriores.

Contexto e problema

Uma transação é uma única unidade de lógica ou trabalho, às vezes composta por múltiplas operações. Dentro de uma transação, um evento é uma mudança de estado que ocorre a uma entidade, e um comando encapsula todas as informações necessárias para realizar uma ação ou desencadear um evento posterior.

As transações devem ser atómicas, consistentes, isoladas e duráveis (ACID). As transações dentro de um único serviço são ACID, mas a consistência dos dados de serviços cruzados requer uma estratégia de gestão de transações de transações de serviços cruzados.

Em arquiteturas multiserviços:

  • A atomicidade é um conjunto indivisível e irredutível de operações que devem ocorrer ou não ocorram.
  • Consistência significa que a transação só traz os dados de um estado válido para outro estado válido.
  • O isolamento garante que as transações simultâneas produzem os mesmos dados que afirmam que as transações executadas sequencialmente teriam produzido.
  • A durabilidade garante que as transações comprometidas permanecem comprometidas mesmo em caso de falha do sistema ou de falta de energia.

Um modelo de base de dados por microserviço proporciona muitos benefícios para as arquiteturas de microserviços. Encapsular os dados de domínio permite que cada serviço utilize o seu melhor tipo de loja de dados e esquema, escalar a sua própria loja de dados, se necessário, e ser isolado das falhas de outros serviços. No entanto, garantir a consistência dos dados através de bases de dados específicas do serviço coloca desafios.

Transações distribuídas como o protocolo de efeto em duas fases (2PC) exigem que todos os participantes numa transação cometam ou revertam antes que a transação possa prosseguir. No entanto, algumas implementações dos participantes, como bases de dados NoSQL e corretagem de mensagens, não suportam este modelo.

Outra limitação de transação distribuída é a sincronização e disponibilidade de comunicação interprocessa (IPC ). O IPC fornecido pelo sistema operativo permite que processos separados partilhem dados. Para as transações distribuídas a efeto, todos os serviços participantes devem estar disponíveis, reduzindo potencialmente a disponibilidade global do sistema. As implementações arquitetónicas com IPC ou limitações de transações são candidatas ao padrão Saga.

Solução

O padrão Saga fornece gestão de transações usando uma sequência de transações locais. Uma transação local é o esforço de trabalho atómico realizado por um participante da saga. Cada transação local atualiza a base de dados e publica uma mensagem ou evento para desencadear a próxima transação local na saga. Se uma transação local falhar, a saga executa uma série de transações compensatórias que desfazem as alterações que foram feitas pelas transações locais anteriores.

Saga overview.

Nos padrões saga:

  • As transações compensatórias são transações que podem potencialmente ser revertidas processando outra transação com o efeito oposto.
  • Uma transação de pivô é o ponto de partida numa saga. Se a transação de pivô se comprometer, a saga funciona até à conclusão. Uma transação de pivô pode ser uma transação que não é compensatória nem repensável, ou pode ser a última transação compensatória ou a primeira transação repensável na saga.
  • As transações retripáveis são transações que seguem a transação de pivô e que têm a garantia de sucesso.

Existem duas abordagens comuns de implementação da saga, coreografia e orquestração. Cada abordagem tem o seu próprio conjunto de desafios e tecnologias para coordenar o fluxo de trabalho.

Coreografia

A coreografia é uma forma de coordenar sagas onde os participantes trocam eventos sem um ponto de controlo centralizado. Com coreografia, cada transação local publica eventos de domínio que desencadeiam transações locais em outros serviços.

Choreography Overview

Benefícios

  • Bom para fluxos de trabalho simples que requerem poucos participantes e não precisam de uma lógica de coordenação.
  • Não requer implementação e manutenção de serviços adicionais.
  • Não introduz um único ponto de insucesso, uma vez que as responsabilidades são distribuídas pelos participantes da saga.

Desvantagens

  • O fluxo de trabalho pode tornar-se confuso ao adicionar novos passos, pois é difícil rastrear quais os participantes da saga que ouvem quais comandos.
  • Há o risco de dependência cíclica entre os participantes da saga porque eles têm que consumir os comandos uns dos outros.
  • Os testes de integração são difíceis porque todos os serviços devem estar em execução para simular uma transação.

Orquestração

A orquestração é uma forma de coordenar sagas onde um controlador centralizado diz aos participantes da saga quais as transações locais a executar. O orquestrador saga trata de todas as transações e diz aos participantes que operação para realizar com base em eventos. O orquestrador executa pedidos de saga, armazena e interpreta os estados de cada tarefa, e lida com a recuperação de falhas com compensações de transações.

Orchestration Overview

Benefícios

  • Bom para fluxos de trabalho complexos envolvendo muitos participantes ou novos participantes adicionados ao longo do tempo.
  • Adequado quando há controlo sobre cada participante no processo, e controlo sobre o fluxo de atividades.
  • Não introduz dependências cíclicas, porque o orquestrador depende unilateralmente dos participantes da saga.
  • Os participantes da Saga não precisam de saber sobre comandos para outros participantes. Uma clara separação de preocupações simplifica a lógica do negócio.

Desvantagens

  • A complexidade adicional do design requer a implementação de uma lógica de coordenação.
  • Há um ponto adicional de fracasso, porque o orquestrador gere o fluxo de trabalho completo.

Problemas e considerações

Considere os seguintes pontos ao implementar o padrão Saga:

  • O padrão Saga pode inicialmente ser um desafio, uma vez que requer uma nova forma de pensar em como coordenar uma transação e manter a consistência de dados para um processo de negócio que abrange vários microserviços.
  • O padrão Saga é particularmente difícil de depurar, e a complexidade aumenta à medida que os participantes aumentam.
  • Os dados não podem ser revertidos, porque os participantes da saga comprometem alterações nas bases de dados locais.
  • A implementação deve ser capaz de lidar com um conjunto de potenciais falhas transitórias e fornecer idempotência para reduzir os efeitos colaterais e garantir a consistência dos dados. Idempotence significa que a mesma operação pode ser repetida várias vezes sem alterar o resultado inicial.
  • É melhor implementar a observabilidade para monitorizar e acompanhar o fluxo de trabalho da saga.
  • A falta de isolamento de dados dos participantes impõe desafios de durabilidade. A implementação da saga deve incluir contramedidas para reduzir anomalias.

As seguintes anomalias podem acontecer sem medidas adequadas:

  • Atualizações perdidas, quando uma saga escreve sem ler alterações feitas por outra saga.
  • Leituras sujas, quando uma transação ou uma saga lê atualizações feitas por uma saga que ainda não completou essas atualizações.
  • Leituras fuzzy/não respeitáveis, quando diferentes passos de saga lêem dados diferentes porque ocorre uma atualização de dados entre as leituras.

As contramedidas sugeridas para reduzir ou prevenir anomalias incluem:

  • Bloqueio semântico, um bloqueio de nível de aplicação onde a transação compensatória de uma saga usa um semáforo para indicar que uma atualização está em andamento.
  • Atualizações comutativas que podem ser executadas em qualquer ordem e produzir o mesmo resultado.
  • Vista pessimista: É possível uma saga ler dados sujos, enquanto outra saga está a executar uma transação compensatória para reverter a operação. A visão pessimista reordena a saga para que os dados subjacentes atualizam uma transação retripvelável, o que elimina a possibilidade de uma leitura suja.
  • O valor reler verifica se os dados estão inalterados e, em seguida, atualiza o registo. Se o registo tiver mudado, os passos abortam e a saga pode reiniciar.
  • Um ficheiro de versão regista as operações num registo à medida que chegam e executa-as na ordem correta.
  • Por valor utiliza o risco comercial de cada pedido para selecionar dinamicamente o mecanismo de concuência. Os pedidos de baixo risco favorecem sagas, enquanto pedidos de alto risco favorecem transações distribuídas.

Quando utilizar este padrão

Use o padrão Saga quando precisar:

  • Garantir a consistência dos dados num sistema distribuído sem um acoplamento apertado.
  • Recue ou compense se uma das operações da sequência falhar.

O padrão Saga é menos adequado para:

  • Transações bem acopladas.
  • Compensação de transações que ocorrem em participantes anteriores.
  • Dependências cíclicas.

Exemplo

A Saga baseada em orquestração em Serverless é uma referência de implementação de saga usando a abordagem de orquestração que simula um cenário de transferência de dinheiro com fluxos de trabalho bem sucedidos e falhados.

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

  • A coreografia tem cada componente do sistema a participar no 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 controlo.
  • Compensar as transações desfazem o trabalho realizado por uma série de passos, e eventualmente definem uma operação consistente se um ou mais passos falharem. Aplicações hospedadas em nuvem que implementam processos de negócio complexos e fluxos de trabalho muitas vezes seguem este modelo de consistência eventual.
  • A Retry permite que uma aplicação lide com falhas transitórias quando tenta ligar-se a um serviço ou recurso de rede, reorientando de forma transparente a operação falhada. A recandidatura pode melhorar a estabilidade da aplicação.
  • O disjuntor lida com falhas que demoram um tempo variável a recuperar, quando se liga a um serviço ou recurso remoto. O disjuntor pode melhorar a estabilidade e a resiliência de uma aplicação.
  • A monitorização do ponto final de saúde implementa controlos funcionais numa aplicação que as ferramentas externas podem aceder através de pontos finais expostos a intervalos regulares. A monitorização do ponto final da saúde pode ajudar a verificar se as aplicações e serviços estão a funcionar corretamente.