GH GambleHub

Exactly-once semântica

O que é exactly-once realmente

Por «exactly-once» muitas vezes se percebe duas coisas diferentes:
  • Uma mensagem será entregue ao consumidor exatamente uma vez.
  • Processamento: Efeito colateral final (gravação no banco de dados, reequilíbrio, emissão de outro evento) ocorrerá exatamente uma vez, mesmo que as entregas ou tentativas tenham sido maiores.

Em sistemas distribuídos, é mais confiável falar de semântica de processamento. A entrega é uma única vez difícil de fornecer (duplicados e repetições são inevitáveis), mas você pode fazer com que o estado final seja equivalente a um único processamento.


Quando o EOS é necessário e quando não

É necessário um EOS se:
  • Transações em dinheiro e balanços: Duplo cancelamento é inadmissível.
  • Registro de licenças/quotas, contadores de billing.
  • Chamadas externas irreversíveis (por exemplo, ativação exclusiva de chave).
Pode-se tratar de at-least-once + idempotação se:
  • Os efeitos são reversíveis ou compensáveis (sagas, devoluções).
  • É permitido duplicar temporariamente em vitrines/logs.
  • É mais barato fornecer um sink idumpotente do que arrastar transações através de todo o caminho.

Modelo: end-to-end vs. hop-by-hop

Hop-by-hop EOS: Cada área (origem → processador → receptor) garante que a sua ação será aplicada exatamente uma vez.
End-to-end EOS: Toda a cadeia garante que o resultado é equivalente a um único processamento.

Na prática, end-to-end é alcançado por uma combinação de transações e/ou idempotação em cada hop.


Blocos básicos de construção

1. Operações Idumpotentes

A repetição da mesma solicitação sobre a chave da operação tem o mesmo resultado.

Ключи: `idempotency_key`/`event_id`/`operation_id`.
Implementação: tabela de operações «vistas» com TTL ≥ retenção do login de entrada.

2. Transações «ler-processar-escrever» (read-processo-write)

Uma unidade de trabalho atômica registra o efeito secundário e o progresso da leitura (ofset/posição). Isso elimina «fantasmas» ao cair entre os passos.

3. Versioning/SEQUENCE

O dispositivo armazena a versão/contagem; as alterações só são aplicadas se 'expected _ version' corresponder. As repetições do mesmo evento não aumentam a versão → o efeito uma vez.

4. Deduplicação

Índice por '(consumer _ id, event _ id)' ou pela operação natural 'business _ id'.


Pattern de implementação

1) Logs de transação + sink de transação com fixação de ofset

Perfeito para processamento de estrim.

Lê a partir do logem (apenas registros confirmados).
Estamos a fazer o processamento.

Em uma transação:
  • a) Gravamos o efeito no sink (BD/tabela),
  • b) registramos «lido antes do ofset N» (no mesmo BD).
  • Uma comitiva. Com o restarte, tudo está forjado (e o ofset é movido) ou nada.

Propriedades: não prejudica a execução; «exatamente uma vez», mesmo que a mensagem tenha sido lida duas vezes.

2) Outbox + Consoador Idumpotente

Para os serviços de transação.

Em uma transação BD, altere a gravação de domínio e escreva o evento em outbox.
O replicador entrega o evento para o pneu com o mesmo 'event _ id'.
Os conceituadores aplicam os eventos de forma idempotiva (deadup por 'event _ id').

Propriedades: O produtor garante que o fato não se perde; os consoantes garantem exatamente um efeito.

3) EOS em Kafka/Flink-sistemas similares (conceitualmente)

Produtor Idumpotent: protege contra dublagens em retais de envio.
Transações do produtor: grupo de gravações em topics + alteração do Consumer Comutação Atomário; os leitores usam o isolamento 'read _ committed'.
O lado do processamento armazena o status (state store) e o configura junto com a transação.

Propriedades: reativar o estore/touca não resulta em duplo efeito; Duplicar «não é visível» downstream.

4) Idempotentes «sikes» (sinks) através de upsert/merge

O Sink aceita 'operation _ id '/' event _ id' e executa 'UPSERT... WHERE NOT EXISTS`.
O efeito colateral (por exemplo, a cobrança) é executado de forma atômica, verificando se já foi aplicado.

Propriedades: método EOS barato na fronteira com o armazenamento, sem transações distribuídas.


Peças-chave de implementação

Identificadores de operação

Devem ser detectados para repetições (não gerem um novo UUID na retraia).
Ter uma área de visibilidade sustentável (por consumer/por unidade/sistema).

Tabela de Deduplicação

Колонки: `consumer_id`, `operation_id`, `applied_at`, `ttl_expires_at`.
Índices por '(consumer _ id, operation _ id)'.
O TTL ≥ a janela máxima de repetição (retenção do logs + potenciais atrasos).

Competição otimista

No modelo write, guarde a versão do aparelho.
Ao aplicar o evento/comando, use 'WHERE versão =: exposed'; a duplicação não aumenta a versão.

Encomenda/ordem

O EOS não é da mesma ordem. Assegure a consistência através da chave de partição (todos os eventos do aparelho → uma única partição) e/ou comparação de 'sequence'.

Chamadas externas idimpotentes

Para métodos inseguros (como webhooks HTTP em um serviço de terceiros), adicione «Idempotency-Key» e exija que o parceiro o apoie.


Armadilhas frequentes

O EOS está apenas em um lugar: se o sink é idumpotental, mas você emite eventos secundários sem idempotação, você receberá «exatamente muitas vezes» downstream.
Duas empresas, primeiro na BD, e depois na corretora, a queda entre elas cria duplicados efeitos.
CDC crus para fora: A alteração da base de dados rompe a idempotação dos consumidores.
As chaves instáveis de 'operation _ id' dependem do tempo/rândomo e mudam ao retraí.


Custos e compromissos

Latitude: transações/leitura isolada → crescimento p95/p99.
Overhead de armazenamento: tabelas de dedução, state stores, logs de transações.
Dificuldade de operação: temporizações de transações, revalidação de fluxos, sessões «vazadas».
Diagnóstico: Mais estados («em camita», «visto como read _ committed», «reversão»).

Selecione o EOS pontualmente para agregados e efeitos críticos; cubra o resto com idoneidade e compensações.


Teste exactly-once

1. Fault-inhation: a queda do processo entre os passos «gravou o efeito» e «registrou o ofset».
2. Duplicado: Balanceie a mesma mensagem 2-5 vezes, verifique um efeito.
3. Restarte e rebalance: paragem/reinício de workers, verificação de falta de duplo processamento.
4. Flappies de rede, temporizações no meio da transação, repetição da empresa.
5. Testes de carga: aumento de filas → se não há degradação para «para sempre na transação».


Mini-modelos (pseudo)

Sink Idumpotente com fixação de ofset

pseudo begin tx if not exists(select 1 from dedup where consumer_id=:c and op_id=:id)
then apply_effect(...)    -- upsert / merge / add_one_time_action insert into dedup(c, id, applied_at) values(:c,:id, now)
end if update offsets set pos=:pos where consumer_id=:c commit

Comando com versão do aparelho

pseudo begin tx update account set balance = balance +:delta,
version = version + 1 where id=:account_id and version=:expected_version;
if row_count=0 then error CONCURRENT_MODIFICATION commit

Segurança e Complacência

PII/PCI nas tabelas de dedução: guarde o mínimo, use os tocantes em vez dos dados «crus».
Auditoria: logue 'operation _ id', 'trace _ id', resultado (APPLIED/ALREADY _ APPLIED).
Política de armazenamento: TTL em tabelas de dados, arquivamento de arquivos/logs.


Anti-pattern

«Presente exactly-once entrega»: tentativa de excluir as duplicações ao nível do protocolo de transporte sem idempotidade de efeito.
Transações globais distribuídas para tudo: XA/2PC através de todos os serviços - frágil e lento.
Mistura de subprodutos não-ideais (por exemplo, e-mail enviado para Comit Offset).
Falta de chaves de operação: confiança em «exclusividade» da carga útil.


Folha de cheque de produção

  • Cada efeito crítico tem uma chave idimpotente.
  • Ofset/posição de leitura é registrado em uma transação de efeito.
  • As tabelas de dedução são indexadas; TTL ≥ retenção do logs.
  • As unidades incluem concorrência otimista (versão/sequence).
  • Os fluxos/topics são lidos no modo «apenas forjados» (se disponíveis).
  • Os testes de duplicação e queda estão presentes em CI/CD.
  • Dashboards: proporção de repetições, transações falhadas, tempo de bloqueio, lagoas.
  • Documentação para integradores por 'Idempotency-Keu '/repetições/temporizações.

FAQ

O EOS pode ser fornecido sem transações?
Muitas vezes sim - através da idempotidade do sink 'ov (upsert/merge) e da versionização das unidades. As transações facilitam as garantias, mas aumentam o custo.

Todos precisam de «exactly-once»?
Não. Ele é querido. Use o ponto onde a compensação é impossível/estrada.

Como associar e-mails/webhooks a EOS?
Selecione a notificação até a comitiva e envie-a depois de fixar o efeito; Guarde 'notification _ id' e faça o envio idimpotente.

O que é mais importante: entrega ou processamento?
Processamento. As entregas podem ser repetidas; O estado final deve ser correto e o único.


Resultado

Exactly-once é sobre o efeito correto, não sobre a falta de dublagem no fio. Ela é alcançada por uma combinação de idempotidade, fixação atômica do efeito e progresso da leitura, partilha inteligente e disciplina de versionização. Use o EOS onde o custo do erro é inaceitável e verifique sua realidade com testes de queda e duplicação - não acredita no transporte.

Contact

Entrar em contacto

Contacte-nos para qualquer questão ou necessidade de apoio.Estamos sempre prontos para ajudar!

Iniciar integração

O Email é obrigatório. Telegram ou WhatsApp — opcionais.

O seu nome opcional
Email opcional
Assunto opcional
Mensagem opcional
Telegram opcional
@
Se indicar Telegram — responderemos também por lá.
WhatsApp opcional
Formato: +indicativo e número (ex.: +351XXXXXXXXX).

Ao clicar, concorda com o tratamento dos seus dados.