Como o Kafka resolve o problema de perda de mensagens

Em toda a arquitetura do Kafka, pode-se concluir que a mensagem possui três processos de entrega:

  1. Lado do produtor envia mensagem para o lado do Broker
  2. Broker processa mensagens e persiste dados
  3. O consumidor extrai e consome mensagens do corretor

A perda de dados pode ocorrer em cada uma das três etapas acima, portanto, em que circunstâncias o Kafka pode garantir que as mensagens não sejam perdidas?

Lado do produtor perdido

Para melhorar a eficiência de envio e reduzir as operações de IO no lado do produtor, várias solicitações são enviadas de forma assíncrona ao enviar uma mensagem, portanto, a perda de mensagem no lado do produtor é maior porque a mensagem não é enviada ao lado do corretor.

Existem as seguintes razões para a falha do produtor em enviar a mensagem:

  • Motivo da rede: Devido ao jitter da rede, os dados não são enviados para o lado do Broker
  • Motivo do dado: O corpo da mensagem é muito grande para ser aceito pelo Broker, fazendo com que o Broker rejeite a mensagem

solução

A perda de dados do lado do Producer é porque ele é enviado de forma assíncrona, então se você usar o método send-and-burn neste momento, ou seja, chamar Producer.send(msg) retornará imediatamente. callback, o Broker pode falhar por motivos de rede A mensagem não é recebida, é perdida neste momento.

Portanto, o problema de perda de mensagens do lado do produtor pode ser resolvido a partir dos seguintes aspectos:

  • Use um método com uma função de notificação de retorno de chamada para enviar uma mensagem
  • Mecanismo de confirmação de ACK
  • número de tentativas

O Produtor confirma se a mensagem foi produzida com sucesso através da configuração do ACK, e os parâmetros de configuração são os seguintes:

  • 0: Como a transmissão é considerada bem-sucedida após a transmissão, se ocorrer instabilidade na rede neste momento, ocorrerá perda de dados
  • 1: A mensagem é enviada para a partição Líder e recebida com sucesso, o que significa que o envio foi bem-sucedido. Enquanto a partição Líder não travar, os dados podem ser garantidos para não serem perdidos. No entanto, se a partição Líder travar , a partição Seguidora ainda não sincronizou dados e não tem ACK. perderá dados
  • -1 ou all: O envio da mensagem precisa esperar que a partição Líder e todas as partições Seguidoras no ISR confirmem o recebimento da mensagem antes que a mensagem seja enviada com sucesso. A confiabilidade é a mais alta, mas não há garantia de que nenhum dado será perdido. Por exemplo: quando existe apenas a partição Líder no ISR, tal torna-se o caso de acks = 1

Lado do corretor perdido

Após o Broker receber os dados, ele persistirá a mensagem no disco de armazenamento. Para melhorar o throughput e o desempenho, ele adota a estratégia de batch flushing assíncrono, ou seja, descarregar o disco de acordo com uma determinada quantidade de mensagens e tempo de intervalo.

Em primeiro lugar, os dados serão armazenados no PageCache.Quanto ao momento de liberar os dados no Cache, é determinado pelo sistema operacional de acordo com sua própria política ou chamando o comando fsync para forçar a liberação do disco. Se o Broker travar antes de sincronizar com a partição Follower e uma nova partição Leader for eleita, os dados da mensagem atrasada serão perdidos.

Como o armazenamento de mensagens no lado do intermediário é liberado em lotes de forma assíncrona, existe a possibilidade de perda de dados. Como o Kafka não fornece uma maneira de sincronizar discos, um único Broker provavelmente perderá dados.

O Kafka conseguiu garantir que os dados não fossem perdidos ao máximo por meio do mecanismo de várias partições e várias cópias. Se os dados foram gravados no PageCache, mas não tiveram tempo de ser liberados no disco, se o O corretor onde ele está localizado desliga repentinamente ou tem uma queda de energia, casos extremos ainda ocorrerão. causar perda de dados.

solução

O motivo da perda de mensagens no lado do Broker é que, por meio da estratégia de liberação de lote assíncrona, os dados são primeiro armazenados no PageCache e depois liberados de forma assíncrona.

Portanto, o Kafka usa várias partições e várias cópias para garantir que os dados não sejam perdidos ao máximo. Pode ser garantido pelos seguintes parâmetros:

  • unclean.leader.election.enable: Este parâmetro indica quais Seguidores são elegíveis para serem eleitos como Líder. Se os dados de um Seguidor estiverem muito atrás do Líder, uma vez eleito como o novo Líder, os dados serão perdidos, então precisamos defini-lo como falso para evitar que isso aconteça.
  • replicação.fator: Este parâmetro indica o número de réplicas de partição. Recomenda-se definir replication.factor >=3, de modo que, se a cópia do Líder falhar, a cópia do Seguidor será eleita como a nova cópia do Líder para continuar a fornecer serviços.
  • min.insync.replicas: Este parâmetro indica quantas cópias da mensagem devem ser gravadas com sucesso no ISR para serem consideradas "confirmadas". Recomenda-se definir min.insync.replicas > 1, para melhorar a persistência da mensagem e garantir que os dados não são perdidos.

Além disso, você precisa garantir que replicação.fator > min.insync.replicas, se forem iguais, enquanto uma réplica travar, a partição inteira não funcionará corretamente, por isso é recomendável defini-la como: replicação. factor = min.insync.replicas +1, maximiza a disponibilidade do sistema.

Lado do consumidor perdido

O processo de consumo de mensagens é dividido principalmente em duas etapas:

  • Extrair dados do Broker
  • Processe a mensagem e envie o registro Offset

O consumidor precisa enviar Offset depois de puxar a mensagem, então os dados podem ser perdidos aqui. As razões para a perda são as seguintes:

  • Possíveis maneiras de enviar Offset automaticamente
  • Envie o Offset primeiro depois de puxar a mensagem e, em seguida, processe a mensagem. Se houver um tempo de inatividade anormal ao processar a mensagem neste momento, uma vez que o Offset já foi enviado, após o reinício do Consumidor, ele retomará o consumo da próxima posição do Offset enviado anteriormente. A mensagem processada não será processada novamente, e a mensagem será perdida para o Consumidor.
  • Depois que a mensagem é puxada, a mensagem é processada primeiro e o Offset é enviado. Se ocorrer um tempo de inatividade anormal antes do envio neste momento, porque o Offset não foi enviado com sucesso, a mensagem será puxada novamente do último Offset depois que o próximo Consumidor reiniciar.No caso de perda de mensagem, mas haverá consumo repetido, aqui somente o próprio negócio pode garantir a idempotência.

solução

A perda de mensagens do lado do consumidor é causada pelo envio do offset após o pull da mensagem, portanto, para não perder dados, a forma correta é: pull data, processar a lógica de negócios e enviar informações de deslocamento do offset de consumo.

Ao mesmo tempo, também é necessário definir o parâmetro enable.auto.commit = false e usar o método de envio manual do deslocamento. Além disso, no caso de mensagens repetidas de consumo, o próprio negócio garante a idempotência, garantindo que apenas um consumo bem-sucedido seja suficiente.

Acho que você gosta

Origin blog.csdn.net/xhaimail/article/details/132324586
Recomendado
Clasificación