Eu estava analisando o que entendi que podemos conseguir com uma única transação, permitindo idempotence=true
idempotência: o produtor Idempotent ativa exatamente uma vez um produtor em um único tópico. Basicamente, cada envio de mensagem tem garantias mais fortes e não será duplicado caso ocorra um erro
Então, se já temos idempotência, por que precisamos de outra propriedade exatamente uma vez no Kafka Stream? O que exatamente diferente entre idempotência e exatamente uma vez
Por que a propriedade exatamente uma vez não está disponível no Kafka Producer normal?
apache-kafka
apache-kafka-streams
Sandeep
fonte
fonte
Respostas:
No ambiente distribuído, a falha é um cenário muito comum que pode ocorrer a qualquer momento. No ambiente Kafka, o broker pode travar, falha na rede, falha no processamento, falha ao publicar mensagens ou falha no consumo de mensagens etc. Esse cenário diferente introduziu diferentes tipos de perda e duplicação de dados.
Cenários de falha
A (falha na confirmação ): o produtor publicou a mensagem com êxito com nova tentativa> 1, mas não pôde receber confirmação devido a falha. Nesse caso, o Producer tentará novamente a mesma mensagem pode apresentar duplicado.
B (processo do produtor falhou em mensagens em lote): produtor que enviou um lote de mensagens com falha, com pouco sucesso publicado. Nesse caso, e assim que o produtor reiniciar, republicará novamente todas as mensagens do lote que introduzirão duplicado no Kafka.
C (Falha ao ignorar e esquecer) O produtor publicou a mensagem com nova tentativa = 0 (acionar e esquecer). Em caso de falha publicada, não será informado e enviará a próxima mensagem, isso fará com que a mensagem seja perdida.
D (Falha no consumidor na mensagem em lote) Um consumidor recebe um lote de mensagens da Kafka e confirma manualmente seu deslocamento (enable.auto.commit = false). Se o consumidor falhar antes de se comprometer com Kafka, na próxima vez que o consumidor consumir os mesmos registros novamente, os quais serão reproduzidos em duplicado no lado do consumidor.
Semântica exatamente uma vez
Para obter a semântica Exatamente uma vez em Kafka, ele usa abaixo de 3 propriedades
Habilitar Idempotent (enable.idempotence = true)
"Observe que ativar a idempotência exige que MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION seja menor ou igual a 5, RETRIES_CONFIG seja maior que 0 e ACKS_CONFIG seja 'todos'. Se esses valores não forem explicitamente definidos pelo usuário, serão escolhidos valores adequados. Se valores incompatíveis forem escolhidos. definido, uma ConfigException será lançada "
Para alcançar a idempotência, o Kafka usa uma identificação exclusiva, que é chamada de identificação do produto ou PID e número de sequência ao produzir mensagens. O produtor continua incrementando o número de sequência em cada mensagem publicada, que mapeia com PID exclusivo. O corretor sempre compara o número de sequência atual com o anterior e rejeita se o novo não for +1 maior que o anterior, o que evita a duplicação e, ao mesmo tempo, se mais do que o maior for perdido nas mensagens
No cenário de falha, o broker comparará o número de sequência com o anterior e, se a sequência não tiver aumentado, +1 rejeitará a mensagem.
Transação (isolamento.nível)
As transações nos permitem atualizar dados atomicamente em várias partições de tópicos. Todos os registros incluídos em uma transação serão salvos com sucesso, ou nenhum deles. Ele permite comprometer as compensações do consumidor na mesma transação, juntamente com os dados que você processou, permitindo, assim, a semântica de ponta a ponta exatamente uma vez. .
O Producer não espera para gravar a mensagem no kafka, onde o Producer usa beginTransaction, commitTransaction e abortTransaction (em caso de falha) O Consumidor usa isolation.level read_committed ou read_uncommitted
Se um consumidor com isolated.level = read_committed alcançar uma mensagem de controle para uma transação que não foi concluída, ele não entregará mais mensagens dessa partição até que o produtor confirme ou anule a transação ou ocorra um tempo limite de transação. O tempo limite da transação é determinado pelo produtor usando a configuração transaction.timeout.ms (padrão 1 minuto).
Exatamente uma vez no produtor e consumidor
Em condições normais, onde temos produtores e consumidores separados. O produtor precisa idempotente e ao mesmo tempo gerenciar transações, para que o consumidor possa usar o isolamento.level para ler apenas read_committed para tornar todo o processo como operação atômica. Isso garante que o produtor sempre sincronize com o sistema de origem. Mesmo a interrupção ou transação do produtor interrompida, sempre será consistente e publique a mensagem ou lote de mensagens como unidade uma vez.
O mesmo consumidor receberá uma mensagem ou lote de mensagens como unidade uma vez.
Exatamente uma vez no Kafka Stream
O Kafka Stream consome mensagens do tópico A, processa e publica mensagem no Tópico B e, uma vez publicado, use commit (confirmação geralmente executada sob cobertura) para liberar todos os dados do armazenamento de estado no disco.
Exatamente uma vez no Kafka Stream é o padrão de leitura-processo-gravação que garante que essas operações sejam tratadas como operações atômicas. Como o Kafka Stream atende ao produtor, ao consumidor e às transações, o Kafka Stream vem com um processamento especial de parâmetros.
processing.guarantee: exatamente_uma vez que forneça automaticamente os parâmetros abaixo que você não precisa definir explicitamente
fonte
O fluxo Kafka oferece a semântica exatamente uma vez do ponto de vista de ponta a ponta (consome de um tópico, processa essa mensagem e depois produz para outro tópico). No entanto, você mencionou apenas o atributo idempotente do produtor . Essa é apenas uma pequena parte da imagem completa.
Deixe-me refazer a pergunta:
Resposta: Como a semântica de entrega exatamente uma vez não está apenas na etapa de produção, mas no fluxo total do processamento. Para alcançar a entrega exata uma vez semanticamente, existem algumas condições que devem ser satisfeitas com a produção e o consumo.
Este é o cenário genérico: O processo A produz mensagens para o tópico T. Ao mesmo tempo, o processo B tenta consumir mensagens do tópico T. Queremos garantir que o processo B nunca processe uma mensagem duas vezes.
Parte do produtor: devemos garantir que os produtores nunca produzam uma mensagem duas vezes. Podemos usar o Kafka Idempotent Producer
Parte do consumidor: Aqui está o fluxo de trabalho básico para o consumidor:
Os passos acima são apenas um caminho feliz. Existem muitas questões que surgem na realidade.
Como existem muitos problemas, a execução da tarefa e o deslocamento da confirmação devem ser atômicos para garantir a semântica de entrega exatamente uma vez no lado do consumidor. Isso não significa que não podemos, mas é preciso muito esforço para garantir a semântica de entrega exata. O Kafka Stream sustenta o trabalho dos engenheiros.
Observou que: o Kafka Stream oferece "processamento de fluxo exatamente uma vez". Refere-se ao consumo de um tópico, materialização do estado intermediário em um tópico Kafka e produção para um. Se nosso aplicativo depende de outros serviços externos (banco de dados, serviços ...), devemos garantir que nossas dependências externas possam garantir exatamente uma vez nesses casos.
TL, DR: exatamente uma vez para o fluxo total, é necessária a cooperação entre produtores e consumidores.
Referências:
fonte