Perguntas da entrevista da fila de mensagens

1. Noções básicas de MQ

1.1 Por que usar o MQ? Vantagens do MQ

  • Resposta curta
    Processamento assíncrono - Em comparação com os métodos seriais e paralelos tradicionais, o rendimento do sistema é melhorado.
    Desacoplamento de aplicativos - os sistemas se comunicam por meio de mensagens e não se preocupam com o processamento de outros sistemas.
    Corte de tráfego - o volume de solicitações pode ser controlado pelo comprimento da fila de mensagens; pode aliviar altas solicitações simultâneas em um curto período de tempo.
    Manuseio de logs - trata de transferências de logs em massa.
    Comunicação de mensagens - As filas de mensagens geralmente possuem mecanismos de comunicação eficientes integrados, portanto, também podem ser usadas para comunicação de mensagem pura. Por exemplo, implemente filas de mensagens ponto a ponto ou salas de bate-papo etc.

  • Resposta detalhada

    • Principalmente: desacoplamento, assíncrono, corte de pico.
    • Desacoplamento: o sistema A envia dados para os três sistemas BCD e os envia por meio de chamadas de interface. E se o sistema E também quiser esses dados? E daí se o sistema C não for mais necessário? A pessoa encarregada do Sistema A quase entrou em colapso... O Sistema A está severamente acoplado a vários outros sistemas confusos. O Sistema A gera um pedaço de dados críticos e muitos sistemas exigem que o Sistema A envie esses dados. Se for utilizado o MQ, o sistema A gera um dado e o envia para o MQ, que precisa de dados para consumir no MQ sozinho. Se o novo sistema precisar de dados, eles podem ser consumidos diretamente do MQ; se um sistema não precisar desses dados, basta cancelar o consumo de mensagens do MQ. Dessa forma, o sistema A não precisa pensar em para quem enviar dados, não precisa manter esse código e não precisa considerar se a chamada foi bem-sucedida ou não atingiu o tempo limite. É um sistema ou módulo que chama vários sistemas ou módulos, as chamadas entre si são muito complicadas e complicadas de manter. Mas, na verdade, essa chamada não precisa chamar diretamente a interface de forma síncrona.Se o MQ for usado para desacoplá-la de forma assíncrona.
    • Assíncrono: quando o sistema A recebe uma solicitação, ele precisa gravar a biblioteca localmente e também precisa gravar a biblioteca nos três sistemas BCD. Leva 3ms para gravar a biblioteca localmente e 300ms, 450ms e 200ms para os três sistemas BCD sistemas para escrever a biblioteca, respectivamente. O atraso total da solicitação final é de 3 + 300 + 450 + 200 = 953 ms, que é próximo a 1 s. O usuário sente que algo está morrendo de lentidão. Um usuário inicia uma solicitação por meio de um navegador. Se for usado o MQ, o sistema A envia continuamente 3 mensagens para a fila do MQ.Se demorar 5ms, o sistema A leva 3 + 5 = 8ms desde aceitar uma requisição até retornar uma resposta ao usuário.
    • Corte de pico: Reduza a pressão no servidor durante os horários de pico.

1.2 Quais são as vantagens e desvantagens das filas de mensagens? Quais são os prós e contras do RabbitMQ?

As vantagens já foram mencionadas acima, ou seja, há benefícios correspondentes em cenários especiais, como desacoplamento, assincronia e corte de pico.

As desvantagens são as seguintes:

Disponibilidade do sistema reduzida

Originalmente, o sistema estava funcionando bem, mas agora você precisa entrar em uma fila de mensagens, e a fila de mensagens trava, e seu sistema não está bom. Portanto, a disponibilidade do sistema será reduzida;

Maior complexidade do sistema

Depois de entrar na fila de mensagens, muitos problemas precisam ser considerados, como: problemas de consistência, como garantir que as mensagens não sejam consumidas repetidamente, como garantir a transmissão confiável de mensagens, etc. Portanto, há mais coisas a considerar e a complexidade aumenta.

problema de consistência

O sistema A retorna sucesso diretamente após o processamento e todos pensam que sua solicitação foi bem-sucedida; mas o problema é que, se os três sistemas de BCD e BD tiverem sucesso na gravação do banco de dados, o resultado é que o sistema C não consegue gravar o banco de dados, o que fazer? fazer? Seus dados são inconsistentes.

Portanto, a fila de mensagens é realmente uma arquitetura muito complexa. Você pode apresentá-la com muitos benefícios, mas terá que fazer várias soluções e arquiteturas técnicas adicionais para evitar as desvantagens que ela traz. Depois de fazer isso bem, você descobrirá isso, mãe. , a complexidade do sistema aumentou em uma ordem de grandeza, talvez 10 vezes mais complicada. Mas no momento crítico, ainda é necessário usá-lo.

1.3 Qual middleware de mensagem sua empresa utiliza no ambiente de produção?

Em primeiro lugar, você pode dizer que tipo de middleware de mensagem sua empresa escolhe, como RabbitMQ, e então fornecer uma análise preliminar da seleção de diferentes tecnologias de middleware MQ.

Por exemplo: Por exemplo, ActiveMQ é um middleware de mensagem antiquado.Muitas empresas domésticas o usaram amplamente no passado e têm funções poderosas.

Mas o problema é que é impossível confirmar se o ActiveMQ pode suportar os cenários complexos de alta simultaneidade, alta carga e alto throughput de empresas de Internet, e raramente é implementado em empresas domésticas de Internet. Além disso, algumas empresas tradicionais usam o ActiveMQ com mais frequência para fazer chamadas assíncronas e desacoplamento do sistema.

Então você pode falar sobre o RabbitMQ, sua vantagem é que ele pode suportar alta simultaneidade, alto rendimento, alto desempenho e possui uma interface de gerenciamento de segundo plano muito completa e conveniente de usar.

Além disso, também oferece suporte a clustering, arquitetura de implantação de alta disponibilidade, suporte a mensagens de alta confiabilidade e funções relativamente completas.

Além disso, após pesquisas, há muitos casos em que grandes empresas domésticas de Internet implantaram clusters RabbitMQ em grande escala para dar suporte a seus próprios negócios, e há muitas empresas domésticas de Internet de pequeno e médio porte que usam RabbitMQ.

Além disso, a comunidade de código aberto do RabbitMQ é muito ativa e versões iterativas com maior frequência são usadas para corrigir bugs encontrados e realizar várias otimizações. Portanto, após uma consideração abrangente, a empresa adotou o RabbitMQ.

No entanto, o RabbitMQ também tem uma falha, ou seja, é desenvolvido com base na linguagem erlang, por isso é difícil analisar o código-fonte interno e também é difícil realizar uma personalização e transformação aprofundada do código-fonte. , requer uma base sólida de linguagem erlang.

Então podemos falar sobre o RocketMQ, que tem código aberto do Alibaba. Ele passou no teste de alta simultaneidade e alto rendimento no ambiente de produção do Alibaba. Tem excelente desempenho e suporta cenários especiais, como transações distribuídas.

Além disso, o RocketMQ é desenvolvido com base na linguagem Java, adequada para leitura aprofundada do código-fonte, podendo, se necessário, resolver problemas de produção online no nível do código-fonte, incluindo desenvolvimento secundário e transformação do código-fonte.

O outro é Kafka. O middleware de mensagem fornecido pelo Kafka tem significativamente menos funções, que são muito menos do que o middleware MQ mencionado acima.

Mas a vantagem do Kafka é que ele foi projetado para cenários como coleta de logs em tempo real de taxa de transferência ultra-alta, sincronização de dados em tempo real e cálculo de dados em tempo real.

Portanto, Kafka é frequentemente usado em conjunto com tecnologias de computação em tempo real (como Spark Streaming, Storm e Flink) no campo de big data. No entanto, raramente é usado em cenários de uso de middleware MQ tradicionais.

1.4 Quais são as vantagens e desvantagens do Kafka, ActiveMQ, RabbitMQ, RocketMQ?

ActiveMQ RabbitMQGenericName RocketMQ kafka ZeroMQ
Rendimento independente Inferior ao RabbitMQ 2,6 w/s (mensagens persistem) 11,6 w/s 17,3 w/s 29w/s
linguagem de desenvolvimento Java Erlang Java Escala/Java C
mantenedor principal Apache Mozilla/Primavera Alibaba Apache iMatix, o fundador faleceu
Maturidade Maduro Maduro A versão de código aberto não está madura o suficiente mais maduro Apenas C, PHP e outras versões são maduras
formulário de inscrição Ponto a ponto (p2p), transmissão (publicação-assinatura) Quatro tipos são fornecidos: direto, tópico, cabeçalhos e fanout. fanout é o modo de transmissão Modo de publicação e assinatura com base no tópico/messageTag e correspondência regular de acordo com o tipo e o atributo da mensagem Modo de publicação e assinatura com base no tópico e correspondência regular de acordo com o tópico ponto a ponto (p2p)
Persistência Suporta uma pequena quantidade de acumulação Suporta uma pequena quantidade de acumulação Suporta muito empilhamento Suporta muito empilhamento não suporta
mensagem sequencial não suporta não suporta apoiar apoiar não suporta
estabilidade de desempenho bom bom geralmente pobre muito bom
modo de cluster Oferece suporte a modos de cluster simples, como 'espera ativa', mas não oferece suporte a modos de cluster avançados. Oferece suporte a clusters simples, modo de 'replicação', suporte ruim para modos de cluster avançados. Modo 'Master-Slave' de vários pares comumente usado, a versão de código aberto precisa alternar manualmente de Slave para Master Cluster sem estado natural 'Líder-Escravo', cada servidor é Mestre e Escravo não suporta
interface de gerenciamento geralmente melhorar geralmente nenhum nenhum

Em resumo, após várias comparações, são feitas as seguintes sugestões:

O sistema geral de negócios precisa introduzir o MQ. No início, todos usavam o ActiveMQ, mas agora é verdade que as pessoas não o usam muito. Não foi verificado em cenários de throughput de grande escala e a comunidade não é muito ativa, então vamos esquecer. Eu pessoalmente não recomendo usar isso;

Mais tarde, todos começaram a usar o RabbitMQ, mas é verdade que a linguagem erlang impediu que um grande número de engenheiros Java a pesquisassem e controlassem profundamente. Para a empresa, está quase em um estado incontrolável, mas é verdade que eles estão abertos fonte, suporte relativamente estável e ativo.

Mas agora mais e mais empresas usarão o RocketMQ, o que é muito bom. Afinal, ele é produzido por Ali, mas a comunidade pode ficar amarela de repente (o RocketMQ foi doado para o Apache no momento, mas a atividade no GitHub não é alta . ) Se você tem absoluta confiança na força técnica de sua empresa, você recomenda usar o RocketMQ, caso contrário, volte e seja honesto e prático RabbitMQ, eles têm uma comunidade ativa de código aberto e definitivamente não serão amarelos.

Portanto, para pequenas e médias empresas com força técnica média e desafios técnicos não particularmente altos, é uma boa escolha usar o RabbitMQ; para grandes empresas, com fortes recursos de pesquisa e desenvolvimento de infraestrutura, é uma boa escolha usar o RocketMQ.

Para cenários como computação em tempo real e coleta de log no campo de big data, usar Kafka é o padrão da indústria, sem problemas, a comunidade é muito ativa e com certeza não será amarelo, sem mencionar que é quase uma especificação factual neste campo em todo o mundo.

1.5 Quais são os problemas comuns do MQ? Como resolver esses problemas?

As perguntas mais frequentes sobre o MQ são:

  • ordem das mensagens
  • Duplicação de mensagens

1.5.1, a ordem da mensagem

A ordem das mensagens significa que as mensagens podem ser consumidas na ordem em que são enviadas.

Suponha que o produtor gere duas mensagens: M1 e M2. Suponha que M1 seja enviado para S1 e M2 seja enviado para S2. Se for necessário garantir que M1 seja consumido antes de M2, o que deve ser feito?
insira a descrição da imagem aqui
solução:

(1) Certifique-se de que o produtor - MQServer - consumidor seja um relacionamento um para um

insira a descrição da imagem aqui
defeito:

  • O paralelismo se tornará o gargalo do sistema de mensagens (débito insuficiente)
  • Mais tratamento de exceções, por exemplo: enquanto houver um problema na ponta do consumidor, todo o fluxo de processamento será bloqueado e teremos que gastar mais energia para resolver o problema de bloqueio.

(2) Evitar por meio de projeto razoável ou decomposição do problema.

  • Na verdade, há um grande número de aplicativos que não se preocupam com
  • A fila não ordenada não significa que as mensagens estão fora de ordem, portanto é uma forma mais razoável de garantir a ordem das mensagens a partir do nível de negócio ao invés de depender apenas do sistema de mensagens.

1.5.2. Duplicação de mensagens

A causa raiz da duplicação de mensagens é: a rede está inacessível.

Portanto, a solução para esse problema é contornar esse problema. Então a pergunta é: o que deve ser feito se o consumidor receber duas mensagens idênticas?

A lógica de negócios para processamento de mensagens no lado do consumidor permanece idempotente. Enquanto a idempotência for mantida, não importa quantas mensagens repetidas cheguem, o resultado final do processamento será o mesmo. Assegure-se de que cada mensagem tenha um número exclusivo e assegure-se de que o processamento bem-sucedido da mensagem e o log da tabela de desduplicação apareçam ao mesmo tempo. Uma tabela de log é usada para registrar os IDs das mensagens que foram processadas com sucesso.Se o ID de uma mensagem recém-chegada já estiver na tabela de log, a mensagem não será mais processada.

1.6. Conte-me sobre a ideia de projetar o MQ?

Por exemplo, para este sistema de enfileiramento de mensagens, vamos considerá-lo sob as seguintes perspectivas:

Em primeiro lugar, este mq deve suportar escalabilidade, ou seja, expandir a capacidade rapidamente quando necessário, para aumentar o throughput e a capacidade, então como fazer isso? Projete um sistema distribuído, consulte o conceito de design de kafka, corretor -> tópico -> partição, cada partição coloca uma máquina e apenas uma parte dos dados é armazenada. Se os recursos não forem suficientes agora, basta adicionar uma partição ao tópico, fazer a migração de dados e adicionar máquinas, você pode armazenar mais dados e fornecer maior rendimento?

Em segundo lugar, você deve considerar se os dados deste mq devem ser desembarcados no disco, certo? Isso deve ser necessário e o disco pode ser usado para garantir que os dados não sejam perdidos se o processo travar. Como ele caiu quando o disco caiu? Escrita sequencial, para que não haja sobrecarga de endereçamento para leitura e gravação de disco aleatório, e o desempenho da leitura e gravação de disco sequencial é muito alto. Essa é a ideia de Kafka.

Em segundo lugar, você considera a disponibilidade do seu mq? Para isso, consulte o mecanismo de garantia de alta disponibilidade do Kafka explicado no link anterior de disponibilidade. Várias cópias -> líder e seguidor -> corretor desliga e reelege o líder para servir ao mundo exterior.

Pode suportar perda de dados 0? Sim, consulte a solução Kafka de perda de dados zero que mencionamos anteriormente.

Dois, RabbitMQ

2.1 O que é RabbitMQ?

RabbitMQ é um middleware de mensagens de código aberto escrito em Erlang e baseado no protocolo AMQP

2.2. Cenários de uso do Rabbitmq

  • Comunicação assíncrona entre serviços
  • consumo sequencial
  • tarefa cronometrada
  • solicitar corte de pico

2.3. Conceitos básicos do RabbitMQ

  • Broker: Simplificando, é a entidade servidora da fila de mensagens
  • Exchange: troca de mensagem, que especifica para qual fila a mensagem é roteada de acordo com as regras
  • Fila: portadora da fila de mensagens, cada mensagem será colocada em uma ou mais filas
  • Binding: Binding, sua função é vincular a troca e a fila de acordo com as regras de roteamento
  • Chave de roteamento: palavra-chave de roteamento, exchange entrega mensagens com base nessa palavra-chave
  • VHost: vhost pode ser entendido como um virtual broker, ou seja, mini-RabbitMQ server. Ele contém fila, troca, ligação etc. independentes, mas o mais importante é que ele possui um sistema de permissão independente, que pode obter controle do usuário dentro do intervalo do vhost. Obviamente, da perspectiva global do RabbitMQ, o vhost pode ser usado como um meio de isolar diferentes permissões (um exemplo típico é que diferentes aplicativos podem ser executados em diferentes vhosts).
  • Produtor: O produtor da mensagem é o programa que entrega a mensagem
  • Consumidor: O consumidor da mensagem é o programa que recebe a mensagem
  • Canal: canal de mensagem, em cada conexão do cliente, vários canais podem ser estabelecidos, e cada canal representa uma tarefa de sessão

Somente Exchange, Queue e RoutingKey podem determinar uma rota exclusiva de Exchange para Queue.

2.4, modo de trabalho RabbitMQ

2.4.1, modo simples (ou seja, o modo de transceptor mais simples)

insira a descrição da imagem aqui

  • Message produz uma mensagem, coloca a mensagem na fila

  • O consumidor da mensagem (consumidor) escuta a fila de mensagens. Se houver uma mensagem na fila, ele a consumirá. Depois que a mensagem for retirada, ela será excluída automaticamente da fila (a mensagem oculta não pode ser processado corretamente pelo consumidor e desapareceu da fila. Se a mensagem for perdida, ela pode ser definida para reconhecimento manual aqui, mas se for definida como reconhecimento manual, a mensagem de reconhecimento deve ser enviada para a fila no tempo após o processamento, caso contrário, causará estouro de memória).

2.4.2, modo de trabalho (competição de recursos)

insira a descrição da imagem aqui

  • O produtor da mensagem coloca a mensagem na fila. Pode haver vários consumidores. O consumidor 1 e o consumidor 2 escutam a mesma fila ao mesmo tempo e a mensagem é consumida. C1 e C2 competem conjuntamente pelo conteúdo da fila de mensagens atual, e quem chegar primeiro é responsável por consumir a mensagem (perigo oculto: no caso de alta simultaneidade, uma determinada mensagem será gerada por padrão para ser compartilhada por vários consumidores , e uma opção (sincronizar) pode ser definida para garantir que uma mensagem só possa ser consumida por um consumidor).

2.4.3, publicar/assinar assinatura de publicação (recursos compartilhados)

insira a descrição da imagem aqui

  • Cada consumidor escuta sua própria fila;
  • O produtor envia a mensagem para o corretor e a troca encaminha a mensagem para cada fila vinculada à troca, e cada fila vinculada à troca receberá a mensagem.

2.4.4, modo de roteamento de roteamento

insira a descrição da imagem aqui

  • O produtor da mensagem envia a mensagem para o switch julgar de acordo com a rota. A rota é uma string (info). A mensagem gerada atualmente carrega o caractere de rota (método do objeto). O switch só pode corresponder à fila de mensagens correspondente a a chave de rota de acordo com a chave de rota.Os consumidores podem consumir mensagens;
  • Definir sequências de roteamento com base em funções de negócios
  • Obtenha a string de função correspondente da lógica do código do sistema e jogue a tarefa de mensagem na fila correspondente.
  • Cenários de negócios: notificação de erro; EXCEÇÃO; função de notificação de erro; notificação de erro tradicional; notificação do cliente; usando roteamento de chave, erros no programa podem ser encapsulados em mensagens e passados ​​para a fila de mensagens, e os desenvolvedores podem personalizar os consumidores. Receber erros em tempo real ;

2.4.5, modo de tópico de tópico (uma espécie de modo de roteamento)

insira a descrição da imagem aqui

  • O sinal de libra asterisco representa um curinga

  • Asteriscos representam várias palavras, marcas de hash representam uma palavra

  • A função de roteamento adiciona correspondência difusa

  • O produtor da mensagem gera uma mensagem e a envia para o switch

  • O switch combina vagamente a fila correspondente de acordo com as regras da chave, e o consumidor ouvinte da fila recebe o consumo de mensagem

(No meu entendimento, é um tipo de correspondência difusa da consulta de roteamento, semelhante ao método de consulta difusa do sql)

2.5 Como garantir a sequência das mensagens do RabbitMQ?

Dividir várias filas, um consumidor para cada fila, apenas mais filas, o que é realmente problemático; ou apenas uma fila, mas corresponde a um consumidor e, em seguida, o consumidor usa internamente as filas de memória para enfileirar e depois as distribui para diferentes trabalhadores na parte inferior tratar.

2.6 Como distribuir a mensagem?

Se a fila tiver pelo menos uma assinatura do consumidor, a mensagem será enviada ao consumidor de maneira round-robin. Cada mensagem será distribuída apenas para um consumidor inscrito (desde que o consumidor possa processar a mensagem normalmente e confirmá-la). A função de multiconsumo pode ser realizada através de roteamento

2.7 Como as mensagens são roteadas?

Provedor de Mensagens -> Roteamento -> Quando uma ou mais mensagens de fila são publicadas na central, a mensagem terá uma chave de roteamento (chave de roteamento), que é definida quando a mensagem é criada. Por meio da chave de roteamento da fila, a fila pode ser vinculada à troca. Depois que a mensagem chegar ao switch, o RabbitMQ fará a correspondência da chave de roteamento da mensagem com a chave de roteamento da fila (existem diferentes regras de roteamento para diferentes switches);

Os interruptores comumente usados ​​são divididos principalmente nos três tipos a seguir:

fanout: Se a central receber uma mensagem, ela será transmitida para todas as filas vinculadas

direto: Se a chave de roteamento corresponder exatamente, a mensagem será entregue na fila correspondente

tópico: permite que mensagens de diferentes origens cheguem à mesma fila. Ao usar a troca de tópicos, você pode usar curingas

2.8 Em que tipo de transmissão se baseia a mensagem?

Devido à alta sobrecarga de criar e destruir conexões TCP, e o número de simultaneidade é limitado pelos recursos do sistema, isso causará gargalos de desempenho. RabbitMQ usa canais para transmitir dados. Um canal é uma conexão virtual estabelecida dentro de uma conexão TCP real e não há limite para o número de canais em cada conexão TCP.

2.9 Como garantir que as mensagens não sejam consumidas repetidamente? Em outras palavras, como garantir a idempotência do consumo de mensagens?

Deixe-me primeiro falar sobre por que há consumo repetido: em circunstâncias normais, quando os consumidores consomem mensagens, eles enviarão uma mensagem de confirmação para a fila de mensagens após o consumo, e a fila de mensagens saberá que a mensagem foi consumida e enviará a mensagem da fila de mensagens excluir em

No entanto, devido à transmissão da rede e outras falhas, as informações de confirmação não foram enviadas para a fila de mensagens, o que fez com que a fila de mensagens não soubesse que já havia consumido a mensagem e distribuísse a mensagem para outros consumidores novamente.

Diante dos problemas acima, uma solução é: garantir a unicidade da mensagem, mesmo que seja transmitida várias vezes, não deixar afetar o consumo múltiplo da mensagem; garantir a idempotência da mensagem;

Por exemplo: quando os dados escritos na fila de mensagens são marcados de forma única, ao consumir a mensagem, julga-se se ela foi consumida de acordo com a marca única;

Suponha que você tenha um sistema que consome uma mensagem e insere um dado no banco de dados. Se você repetir uma mensagem duas vezes, irá inserir dois pedaços. Os dados não estão errados? Mas se você consumir pela segunda vez, julgue por si mesmo se já o consumiu e, em caso afirmativo, jogue-o fora, para que um dado não seja retido, garantindo assim a exatidão dos dados.

2.10 Como garantir que as mensagens sejam enviadas ao RabbitMQ corretamente? Como garantir que o destinatário da mensagem consuma a mensagem?

2.10.1, modo de confirmação do remetente

Se o canal estiver definido para o modo de confirmação (o modo de confirmação do remetente), todas as mensagens publicadas no canal receberão um ID exclusivo.

Assim que a mensagem for entregue à fila de destino ou gravada no disco (mensagem persistente), o canal enviará uma confirmação (incluindo o ID exclusivo da mensagem) ao produtor.

Se ocorrer um erro interno no RabbitMQ e a mensagem for perdida, uma mensagem nack (notacknowledged, unacknowledged) será enviada.

O padrão de confirmação do remetente é assíncrono e o aplicativo produtor pode continuar enviando mensagens enquanto espera por uma confirmação. Quando uma mensagem de confirmação chega ao aplicativo produtor, o método de retorno de chamada do aplicativo produtor é acionado para processar a mensagem de confirmação.

2.10.2. Mecanismo de Confirmação do Receptor

Os consumidores devem confirmar após receber cada mensagem (a recepção da mensagem e a confirmação da mensagem são duas operações diferentes). O RabbitMQ pode excluir com segurança a mensagem da fila somente se o consumidor confirmar a mensagem.

O mecanismo de timeout não é usado aqui, e o RabbitMQ apenas confirma se a mensagem precisa ser reenviada por meio da interrupção da conexão do Consumer. Em outras palavras, desde que a conexão não seja interrompida, o RabbitMQ dá ao consumidor tempo suficiente para processar a mensagem. Assegurar a consistência final dos dados;

Alguns casos especiais estão listados abaixo

  • Se um consumidor receber uma mensagem e desconectar ou cancelar a assinatura antes da confirmação, o RabbitMQ considerará que a mensagem não foi distribuída e a redistribuirá para o próximo consumidor inscrito. (Pode haver perigos ocultos de consumo repetido de mensagens, que precisam ser desduplicadas)
  • Se o consumidor receber a mensagem, mas não confirmar a mensagem e a conexão não for desconectada, o RabbitMQ considera que o consumidor está ocupado e não distribuirá mais mensagens ao consumidor.

2.11 Como garantir a transmissão confiável das mensagens do RabbitMQ?

Mensagens não confiáveis ​​podem ser causadas por perda de mensagem, sequestro, etc.;

Lost é dividido em: mensagem perdida do produtor, mensagem perdida da lista de mensagens, mensagem perdida do consumidor;

2.11.1. O produtor perde a mensagem

Do ponto de vista dos produtores que perdem dados, o RabbitMQ fornece modos de transação e confirmação para garantir que os produtores não percam mensagens;

O mecanismo de transação significa: antes de enviar a mensagem, inicie a transação (channel.txSelect()), e então envie a mensagem. Se ocorrer alguma exceção durante o processo de envio, a transação será revertida (channel.txRollback()), e se o envio for bem sucedido, a transação será submetida (channel. txCommit()). No entanto, esse método tem uma desvantagem: a taxa de transferência cai;

O modo de confirmação é o mais usado: assim que o canal entrar no modo de confirmação, todas as mensagens publicadas no canal receberão um ID exclusivo (começando em 1), uma vez que a mensagem é entregue a todas as filas correspondentes;

rabbitMQ enviará um ACK para o produtor (incluindo o ID único da mensagem), o que faz com que o produtor saiba que a mensagem chegou corretamente à fila de destino;

Se o rabbitMQ falhar ao processar a mensagem, ele enviará a você uma mensagem Nack e você poderá repetir a operação.

2.11.2. Fila de mensagens perde dados

Persistência da mensagem.
Para lidar com a perda de dados na fila de mensagens, geralmente é necessário habilitar a configuração do disco permanente.

Essa configuração persistente pode ser usada em conjunto com o mecanismo de confirmação.Você pode enviar um sinal de ACK ao produtor depois que a mensagem é persistida no disco.

Dessa forma, se o rabbitMQ morrer antes que a mensagem seja persistida no disco, o produtor não receberá o sinal Ack e o reenviará automaticamente.

Então, como persistir?

A propósito, é realmente muito fácil, basta seguir os próximos dois passos

  • Defina o identificador persistente durável da fila como verdadeiro, o que significa que é uma fila persistente
  • Ao enviar uma mensagem, defina deliveryMode=2

Após esta configuração, mesmo que o rabbitMQ desligue, os dados podem ser restaurados após a reinicialização

2.11.3. Consumidores perdem mensagens

Os consumidores geralmente perdem dados porque usam o modo de mensagem de confirmação automática, apenas confirme manualmente a mensagem!

Após o consumidor receber a mensagem, antes de processar a mensagem, ele responderá automaticamente que o RabbitMQ recebeu a mensagem;

Se o processamento da mensagem falhar neste momento, a mensagem será perdida;

Solução: Depois de processar a mensagem com sucesso, responda manualmente à mensagem de confirmação.

2.12 Por que o mecanismo de persistência não deve ser usado para todas as mensagens?

Em primeiro lugar, isso inevitavelmente levará a uma diminuição no desempenho, porque gravar no disco é muito mais lento do que gravar na RAM, e a taxa de transferência de mensagens pode ter uma diferença de 10 vezes.

Em segundo lugar, quando o mecanismo de persistência de mensagens é usado na solução de cluster integrada do RabbitMQ, haverá um problema de "fraude". A contradição é que, se a mensagem for definida com o atributo persistente, mas a fila não for definida com o atributo durável, quando o nó proprietário da fila for anormal, a mensagem enviada para a fila será bloqueada antes que a fila seja reconstruída ; se a mensagem for definida como atributo persistente e a fila também for definida com o atributo durável, quando o nó proprietário da fila for anormal e não puder ser reiniciado, a fila não poderá ser reconstruída em outros nós e o uso da fila só pode ser retomado depois que o nó proprietário for reiniciado e as mensagens enviadas para a fila durante esse período serão bloqueadas.

Portanto, persistir ou não a mensagem requer uma consideração abrangente dos requisitos de desempenho e possíveis problemas. Se você deseja obter uma taxa de transferência de mensagens de mais de 100.000 mensagens por segundo (um único servidor RabbitMQ), deve usar outros métodos para garantir a entrega confiável de mensagens ou usar um sistema de armazenamento muito rápido para suportar persistência total (como usar SSD ). Outro princípio de processamento é: persista apenas as mensagens-chave (de acordo com a importância do negócio), e deve-se garantir que a quantidade de mensagens-chave não cause gargalos de desempenho.

2.13 Como garantir alta disponibilidade? Cluster de RabbitMQ

RabbitMQ é mais representativo, pois é baseado em master-slave (não distribuído) para alta disponibilidade, usaremos RabbitMQ como exemplo para explicar como atingir alta disponibilidade do primeiro MQ. O RabbitMQ possui três modos: modo autônomo, modo de cluster comum e modo de cluster espelhado.

2.13.1, modo autônomo

Está no nível de demonstração. Geralmente, você o inicia localmente para se divertir. Ninguém usa o modo autônomo para produção.

2.13.2. Modo de cluster comum

Isso significa iniciar várias instâncias do RabbitMQ em várias máquinas, uma para cada máquina. A fila que você criar será colocada apenas em uma instância do RabbitMQ, mas cada instância sincronizará os metadados da fila (os metadados podem ser considerados como algumas informações de configuração da fila, através dos metadados, você pode encontrar a instância onde a fila está localizada ). Ao consumir, se você realmente se conectar a outra instância, essa instância extrairá dados da instância em que a fila está localizada. Esta solução visa principalmente melhorar o throughput, ou seja, permitir que vários nós do cluster atendam às operações de leitura e gravação de uma determinada fila.

2.13.3, modo de cluster espelhado

Este modo é o chamado modo de alta disponibilidade do RabbitMQ. Diferente do modo de cluster normal, no modo de cluster de espelho, a fila que você criar, independentemente dos metadados ou das mensagens na fila, existirá em várias instâncias, ou seja, cada nó RabbitMQ possui uma cópia completa da fila Imagem espelhada, incluindo todos os dados da fila. Então, toda vez que você escrever uma mensagem na fila, a mensagem será sincronizada automaticamente com as filas de várias instâncias. RabbitMQ tem um console de gerenciamento muito bom, que consiste em adicionar uma política em segundo plano. Esta política é uma política de modo de cluster de espelhamento. Quando especificada, pode exigir que os dados sejam sincronizados para todos os nós ou para um número especificado de nós. Novamente Ao criar uma fila, aplicar esta estratégia sincronizará automaticamente os dados com outros nós. Nesse caso, a vantagem é que se alguma de suas máquinas estiver inoperante, tudo bem, outras máquinas (nós) também contêm os dados completos dessa fila, e outros consumidores podem ir a outros nós para consumir dados. A desvantagem é que, primeiro, a sobrecarga de desempenho é muito alta.As mensagens precisam ser sincronizadas para todas as máquinas, resultando em grande pressão e consumo de largura de banda da rede! Os dados de uma fila RabbitMQ são armazenados em um nó. Sob o cluster de espelhos, cada nó também armazena os dados completos da fila.

2.14 Como resolver o problema de atraso e expiração da fila de mensagens? O que devo fazer quando a fila de mensagens estiver cheia? Existem milhões de mensagens atrasadas por horas, como resolver isso?

2.14.1, método de processamento de backlog de mensagens

Expansão de emergência temporária:

Primeiro corrija o problema do consumidor para garantir que sua velocidade de consumo seja restaurada e, em seguida, interrompa os consumidores existentes.
Crie um novo tópico, a partição é 10 vezes a original e estabeleça temporariamente o número da fila 10 vezes a original.
Em seguida, escreva um programa consumidor temporário para distribuir dados. Este programa é implantado para consumir o backlog de dados. Após o consumo, ele não executa processamento demorado e pesquisa e grava diretamente e uniformemente 10 vezes o número de filas estabelecidas temporariamente.
Em seguida, requisite temporariamente 10 vezes o número de máquinas para implantar consumidores, e cada lote de consumidores consome dados de uma fila temporária. Essa abordagem é equivalente a expandir temporariamente os recursos da fila e os recursos do consumidor em 10 vezes e consumir dados a uma velocidade normal de 10 vezes.
Depois que o backlog de dados é consumido rapidamente, a arquitetura de implantação original deve ser restaurada e a máquina consumidora original deve ser usada para consumir mensagens novamente.

2.14.2. Falha de mensagem no MQ

Supondo que você esteja usando o RabbitMQ, o RabbtiMQ pode definir o tempo de expiração, que é TTL. Se a mensagem ficar acumulada na fila por mais de um determinado período de tempo, ela será limpa pelo RabbitMQ e os dados serão removidos. Então este é o segundo poço. Isso não quer dizer que uma grande quantidade de dados será acumulada no mq, mas que uma grande quantidade de dados será perdida diretamente. Podemos adotar uma solução, ou seja, redirecionamento em lote, o que já fizemos em cenários semelhantes online antes. Quando tem um backlog grande, a gente descarta os dados direto naquele horário, e depois do horário de pico, por exemplo, todo mundo toma café e fica acordado até depois das 12h, e os usuários estão todos dormindo. Nesse momento, começamos a escrever o programa, escrever um programa temporário para o lote de dados perdidos, verificá-lo pouco a pouco e recarregá-lo no mq para compensar os dados perdidos durante o dia. Só pode ser assim. Supondo que 10.000 pedidos estão pendentes no MQ e não foram processados, e 1.000 deles foram perdidos, você só pode escrever manualmente um programa para descobrir esses 1.000 pedidos e enviá-los manualmente ao MQ para compensar novamente.

2.14.3, o bloco da fila de mensagens mq está cheio

Se a mensagem estiver acumulada no mq e você não a descartar há muito tempo, o mq está quase cheio neste momento, o que você deve fazer? Existe alguma outra maneira de fazer isso? Não, quem te disse que a execução do primeiro plano é muito lenta, você escreve o programa temporariamente, acessa os dados para consumo, consome um e descarta o outro, e consome rapidamente todas as mensagens. Em seguida, vá para o segundo plano e componha os dados à noite.

três, kafka

3.1 O que é Apache Kafka?

O Apache Kafka é uma estrutura de processamento de fluxo distribuído para criar aplicativos de processamento de fluxo em tempo real. Ele tem uma função central amplamente conhecida, ou seja, é amplamente utilizado como um mecanismo de mensagens de nível corporativo.

3.2 O que é um grupo de consumidores?

Grupo de consumidores é um conceito único de Kafka

  • Definição: O grupo de consumidores é um mecanismo de consumidor escalável e tolerante a falhas fornecido pelo Kafka.
  • Princípio: Em Kafka, um grupo de consumidores é um grupo composto por várias instâncias de consumidores. Múltiplas instâncias se inscrevem conjuntamente em vários tópicos para alcançar o consumo comum. Cada instância no mesmo grupo é configurada com o mesmo ID de grupo e atribuída a uma partição de assinatura diferente. Quando uma instância desliga, outras instâncias assumirão automaticamente a partição que é responsável pelo consumo.

3.3 Qual é o papel do ZooKeeper no Kafka?

Atualmente, o Kafka usa o ZooKeeper para armazenar metadados de cluster, gerenciamento de membros, eleição de controlador e outras tarefas de gerenciamento. Depois disso, após a conclusão da proposta KIP-500, Kafka não dependerá mais do ZooKeeper.

Lembre-se de destacar o "agora" para mostrar que você conhece muito bem os planos de evolução da sua comunidade. "Armazenar metadados" significa que todos os dados da partição do tópico são armazenados no ZooKeeper, e os dados armazenados nele são a autoridade e outras "pessoas" devem manter o alinhamento com ele. "Gerenciamento de membros" refere-se ao registro, cancelamento de registro e alterações de atributos de nós do Broker, etc. "Eleição do controlador" refere-se à eleição do controlador do cluster e outras tarefas de gerenciamento incluem, entre outras, exclusão de tópicos, configuração de parâmetros, etc.

No entanto, lançar o KIP-500 também pode ser uma faca de dois gumes. Se você encontrar um entrevistador muito experiente, ele poderá perguntar para que serve o KIP-500. Resumindo: a ideia do KIP-500 é usar o algoritmo de consenso baseado em Raft desenvolvido pela comunidade para substituir o ZooKeeper e realizar a autoeleição do Controlador.

3.4. Explique o papel do deslocamento (offset) em Kafka

No Kafka, cada mensagem em cada partição de tópico recebe um valor de ID exclusivo para identificar sua posição na partição. Esse valor de ID é chamado de deslocamento ou deslocamento. Depois que uma mensagem é gravada em um log particionado, seu valor de deslocamento não pode ser modificado.

3.5. Explique a diferença entre a réplica líder (réplica líder) e a réplica seguidora (réplica seguidora) no Kafka

As réplicas Kafka são atualmente divididas em réplicas líderes e réplicas seguidoras. Somente a cópia do Líder pode fornecer serviços externos de leitura e gravação e responder às solicitações dos Clientes. A cópia do Seguidor usa apenas PULL para sincronizar passivamente os dados na cópia do Líder e está pronta para solicitar a cópia do Líder a qualquer momento após a desativação do Broker onde a cópia do Líder está localizada.

De um modo geral, apenas 60% das respostas foram respondidas nessa medida, portanto, sugiro que você responda dois itens de bônus adicionais.

  • Enfatize que a cópia do Seguidor também pode fornecer serviços de leitura externos. Desde o Kafka 2.4, a comunidade permite que as réplicas do Follower forneçam serviços de leitura limitados, introduzindo novos parâmetros do lado do Broker.
  • Enfatize que as sequências de mensagens do Líder e do Seguidor são inconsistentes em cenários reais. Muitos motivos podem causar inconsistência entre as sequências de mensagens salvas pelo Líder e pelo Seguidor, como bugs de programa e problemas de rede. Este é um erro grave e deve ser totalmente evitado. Você pode acrescentar que o principal meio para garantir a consistência era o mecanismo de marca d'água alta, mas o valor da marca d'água alta não pode garantir a consistência dos dados no cenário em que o líder muda continuamente. Portanto, a comunidade introduziu o mecanismo Leader Epoch para corrigir as desvantagens do valor da marca d'água alta. Em relação ao "Mecanismo de Época Líder", não há muitos materiais domésticos e sua popularidade é muito menor do que a da marca d'água. Você também pode mostrar esse conceito com ousadia e se esforçar para ser incrível.

3.6 Como definir o tamanho máximo de mensagem que o Kafka pode receber?

  • Parâmetros do lado do corretor: message.max.bytes, max.message.bytes (nível de tópico) e replica.fetch.max.bytes.
  • Parâmetros do consumidor: fetch.message.max.bytes.

O último parâmetro do lado do Broker é relativamente fácil de perder. Devemos ajustar o tamanho da maior mensagem que a réplica do Seguidor pode receber, caso contrário, a sincronização da réplica falhará.

3.7 Quais são as estruturas para monitorar o Kafka?

  • Kafka Manager: Deve ser considerado a estrutura de monitoramento Kafka dedicada mais famosa e é um sistema de monitoramento independente.
  • Kafka Monitor: a estrutura de código aberto gratuita do LinkedIn suporta testes de sistema de clusters e monitoramento em tempo real dos
    resultados dos testes.
  • CruiseControl: também é uma estrutura de monitoramento de código aberto do LinkedIn, usada para monitorar o uso de recursos em tempo real e fornecer operações comuns de operação e manutenção. Nenhuma interface de interface do usuário, apenas fornece API REST
  • Monitoramento JMX: Como os indicadores de monitoramento fornecidos pelo Kafka são todos baseados em JMX, qualquer framework do mercado que possa integrar JMX pode ser utilizado, como Zabbix e Prometheus.
  • As plataformas de big data já possuem seu próprio sistema de monitoramento: plataformas de big data como CDH fornecidas pela Cloudera fornecem naturalmente soluções de monitoramento Kafka.
  • JMXTool: Uma ferramenta de linha de comando fornecida pela comunidade que pode monitorar indicadores JMX em tempo real. Responder a esta é um item de bônus absoluto, porque poucas pessoas sabem disso, e dará às pessoas a sensação de que você está muito familiarizado com as ferramentas Kafka. Se você não entender seu uso por enquanto, poderá executar kafka-run-class.sh kafka.tools.JmxTool na linha de comando sem parâmetros para aprender seu uso.

3.8 Como definir o Heap Size do Broker?

Qualquer configuração de tamanho de heap JVM de processo Java precisa ser cuidadosamente considerada e testada. Uma prática comum é executar o programa com o tamanho de heap JVM inicial padrão.Quando o sistema atingir um estado estável, acione manualmente um Full GC e, em seguida, use a ferramenta JVM para visualizar o tamanho dos objetos sobreviventes após o GC. Depois disso, defina o tamanho da pilha para 1,5 a 2 vezes o tamanho total dos objetos sobreviventes. Para Kafka, esse método também é aplicável. No entanto, há uma prática recomendada no setor, que é fixar o tamanho de heap do corretor em 6 GB. Após verificação por muitas empresas, esse tamanho é suficiente e bom.

3.9 Como estimar o número de máquinas no cluster Kafka?

Esta questão examina a relação entre o número de máquinas e os recursos utilizados. Os chamados recursos, ou seja, CPU, memória, disco e largura de banda.

De um modo geral, é mais fácil garantir recursos suficientes de CPU e memória, portanto, você precisa avaliar o número de máquinas a partir das duas dimensões de espaço em disco e largura de banda.

Ao estimar o uso do disco, você não deve esquecer de calcular a sobrecarga da sincronização da réplica. Se uma mensagem ocupa 1 KB de espaço em disco, então, em um tópico com 3 réplicas, você precisa de um total de 3 KB para armazenar a mensagem

Para largura de banda de avaliação, as larguras de banda comuns são 1 Gbps e 10 Gbps, mas você deve ter em mente que esses dois números são apenas valores máximos. Portanto, é melhor confirmar com o entrevistador qual é a largura de banda fornecida. Então, fica claro que quando a largura de banda está próxima de 90% da largura de banda total, ocorre a perda de pacotes. Isso mostrará suas habilidades básicas de rede.

3.10, Líder é sempre -1, como quebrá-lo?

No ambiente de produção, você deve ter encontrado a situação de "uma determinada partição de tópico não pode funcionar". Se você usar a linha de comando para verificar o status, descobrirá que o Líder é -1, então você pode usar vários comandos sem sucesso e, finalmente, você só pode usar "reiniciar o Dafa".

No entanto, existe alguma maneira de resolver este problema sem reiniciar o cluster?Esta é a origem desta questão.

Resposta de referência: exclua o nó/controlador ZooKeeper para acionar a reeleição do controlador. A reeleição do controlador pode atualizar novamente o status da partição para todas as partições de tópico, o que pode resolver efetivamente o problema de indisponibilidade do Líder causado por inconsistência.

3.11 Qual é o design de Kafka?

Kafka resume mensagens em unidades de tópicos

Os programas que publicarão mensagens em um tópico Kafka são chamados de produtores.

O programa que assina tópicos e consome mensagens torna-se um consumidor.

O Kafka é executado como um cluster e pode consistir em um ou mais serviços, cada serviço é chamado de broker.

Os produtores enviam mensagens para o cluster Kafka pela rede e o cluster fornece mensagens aos consumidores

3.12 Quais são as três definições de transação para transmissão de dados?

As definições de transação para transferências de dados geralmente têm os três níveis a seguir:

  • No máximo uma vez: a mensagem não será enviada repetidamente, será transmitida no máximo uma vez, mas não poderá ser transmitida uma vez

  • Pelo menos uma vez: A mensagem não será perdida e transmitida pelo menos uma vez, mas poderá ser transmitida repetidamente.

  • Exatamente uma vez: Não haverá transmissões perdidas ou repetidas. Cada mensagem é transmitida uma vez e
    apenas uma vez, que é o que todos esperam

3.13. Transação Kafka

O Kafka introduziu o suporte a transações desde a versão 0.11. As transações podem garantir o Kafka com base na semântica Exactly Once, a produção e o consumo podem atravessar partições e sessões, todas bem-sucedidas ou falhadas.

  • Negócio do produtor

Para implementar transações entre partições e sessões, um ID de transação globalmente exclusivo precisa ser introduzido e o PID obtido pelo produtor deve estar vinculado ao ID de transação. Desta forma, quando o Produtor for reiniciado, o PID original pode ser obtido através do Transaction ID em andamento.

Para gerenciar a Transação, o Kafka apresenta um novo componente Coordenador da Transação. O Produtor obtém o status da tarefa correspondente ao ID da Transação interagindo com o Coordenador da Transação. O Coordenador de transações também é responsável por gravar todas as transações em um tópico interno do Kafka, de modo que, mesmo que todo o serviço seja reiniciado, uma vez que o estado da transação é salvo, o estado da transação em andamento pode ser restaurado e continuar.

  • Assuntos do consumidor

O mecanismo de transação acima é considerado principalmente da perspectiva do Produtor.Para o Consumidor, a garantia da transação é relativamente fraca, especialmente as informações do Commit não podem ser garantidas para serem consumidas com precisão. Isso ocorre porque os consumidores podem acessar informações arbitrárias por meio de compensação, e diferentes arquivos de segmento têm ciclos de vida diferentes e as mensagens da mesma transação podem ser excluídas após a reinicialização.

3.14 Quais são as duas condições para Kafka julgar se um nó ainda está vivo?

  • O nó deve ser capaz de manter uma conexão com o ZooKeeper, e o Zookeeper verifica a conexão de cada nó por meio do mecanismo de pulsação

  • Se o nó for um seguidor, ele deve ser capaz de sincronizar a operação de gravação do líder no tempo e o atraso não deve ser muito longo

3.15 O produtor envia dados diretamente para o líder da corretora (nó mestre)?

O produtor envia os dados diretamente para o líder do broker (nó primário), sem distribuí-los entre vários nós. Para ajudar o
produtor a fazer isso, todos os nós Kafka podem ser notificados a tempo: quais nós estão ativos, o
tópico alvo alvo Onde é o líder da partição. Desta forma, o produtor pode enviar a mensagem diretamente para o destino

3.16 O consumidor Kafa pode consumir mensagens de partição especificadas?

Quando um consumidor Kafa consome uma mensagem, ele envia uma requisição "fetch" para o broker consumir a mensagem de uma partição específica. O consumidor especifica o offset (offset) da mensagem no log, podendo consumir a mensagem a partir desta posição. O cliente tem o controle do deslocamento Certo, você pode reverter para consumir novamente a mensagem anterior, o que é muito significativo

3.17. A mensagem Kafka usa o modo Pull ou o modo Push?

A consideração inicial de Kafka é se os clientes devem receber mensagens dos corretores ou os corretores enviarem mensagens aos consumidores, ou seja, puxar ou empurrar. A esse respeito, o Kafka segue um design tradicional comum à maioria dos sistemas de mensagens: os produtores enviam mensagens aos corretores e os consumidores recebem mensagens dos corretores.

Alguns sistemas de mensagens, como Scribe e Apache Flume, adotam o modo push para enviar mensagens aos consumidores downstream. Existem vantagens e desvantagens em fazer isso: a taxa na qual as mensagens são enviadas é determinada pelo broker, o que não é fácil de lidar para consumidores com diferentes taxas de consumo. O sistema de mensagens está comprometido em permitir que o consumidor consuma mensagens na taxa mais rápida na taxa máxima, mas infelizmente, no modo push, quando a taxa empurrada pelo corretor é muito maior que a taxa consumida pelo consumidor, o consumidor pode colapso.

No final, Kafka escolheu o modo pull tradicional.

Outro benefício do modo Pull é que o consumidor pode decidir independentemente se deseja extrair dados do corretor em lotes.

O modo Push deve decidir se enviará cada mensagem imediatamente ou enviará em lotes após o armazenamento em cache sem conhecer a capacidade de consumo e a estratégia de consumo do consumidor a jusante. Se uma taxa de envio mais baixa for usada para evitar travamentos do consumidor, isso pode resultar em um desperdício de menos mensagens sendo enviadas por vez.

No modo Pull, o consumidor pode decidir essas estratégias de acordo com sua própria capacidade de consumo

Uma desvantagem do Pull é que, se o intermediário não tiver mensagens para consumir, isso fará com que o consumidor continue pesquisando em um loop até que novas mensagens cheguem. Para evitar isso, o Kafka possui um parâmetro que permite aos consumidores bloquear até que novas mensagens cheguem (claro, também pode bloquear até que o número de mensagens atinja um determinado valor para que possam ser puxadas em lotes)

3.18 Qual é o formato da mensagem do Kafka armazenada no disco rígido?

As mensagens consistem em um cabeçalho de comprimento fixo e matrizes de bytes de comprimento variável. O cabeçalho contém um número de versão e
um checksum CRC32.

  • Comprimento da mensagem: 4 bytes (valor: 1+4+n)
  • Número da versão: 1 byte
  • Código de verificação CRC: 4 bytes
  • Mensagem específica: n bytes

3.19, recursos de design de armazenamento de arquivos eficientes do Kafka

  • O Kafka divide um grande arquivo de partição em um tópico em vários segmentos de arquivos pequenos. Por meio de vários segmentos de arquivos pequenos, é fácil limpar
    ou excluir arquivos consumidos regularmente e reduzir o uso do disco.

  • As informações de índice podem localizar rapidamente a mensagem e determinar o tamanho máximo da resposta.

  • Ao mapear todos os metadados de índice para a memória, a operação de disco IO do arquivo de segmento pode ser evitada.

  • O armazenamento esparso de arquivos de índice pode reduzir muito o espaço ocupado pelos metadados do arquivo de índice.

3.20 Existem três diferenças principais entre o Kafka e os sistemas de mensagens tradicionais

  • Logs persistentes do Kafka, que podem ser lidos repetidamente e retidos indefinidamente

  • O Kafka é um sistema distribuído: ele é executado como um cluster, pode ser escalado de forma flexível e replica internamente os dados para melhorar a tolerância a falhas e a alta disponibilidade

  • Kafka suporta streaming em tempo real

3.21. Como colocar partições em diferentes Brokers quando Kafka cria um tópico

O fator de replicação não pode ser maior que o número de Brokers;

A posição de colocação da primeira cópia da primeira partição (numerada como 0) é selecionada aleatoriamente na brokerList; as posições de colocação das primeiras cópias de outras partições são movidas para trás em relação à 0ª partição. Ou seja, se tivermos 5 Brokers e 5 partições, supondo que a primeira partição seja colocada no quarto Broker, então a segunda partição será colocada no quinto Broker, a terceira partição será colocada no quinto Broker. ; a quarta partição será colocada no segundo Broker, e assim sucessivamente;

A posição das réplicas restantes em relação à primeira réplica é realmente determinada por nextReplicaShift, e esse número também é gerado aleatoriamente

3.22 Em qual diretório será criada a partição recém-criada do Kafka?

Antes de iniciar o cluster Kafka, precisamos configurar o parâmetro log.dirs, cujo valor é o diretório de armazenamento dos dados Kafka. Este parâmetro pode configurar vários diretórios separados por vírgulas. Geralmente esses diretórios são distribuídos em discos diferentes. Para melhorar a leitura e
gravação desempenho.

Claro, também podemos configurar o parâmetro log.dir, que tem o mesmo significado. Apenas um deles precisa ser definido.

Se o parâmetro log.dirs estiver configurado com apenas um diretório, então as partições atribuídas a cada Broker deverão
criar apenas pastas neste diretório para armazenamento de dados.

Mas se o parâmetro log.dirs configurar vários diretórios, em qual pasta o Kafka criará o diretório de partição?
A resposta é: Kafka criará um novo diretório de partição na pasta que contém o menor diretório de partição e o nome do diretório de partição é Nome do tópico + ID da partição. Observe que é o diretório com o menor número total de pastas de partição, não o diretório com o menor uso de disco! Ou seja, se você adicionar um novo disco ao parâmetro log.dirs, o novo diretório de partição deverá ser criado primeiro nesse novo disco até que o novo diretório de disco não tenha o menor número de diretórios de partição.

3.23. Como salvar dados de partição no disco rígido

Várias partições no tópico são salvas no broker na forma de pastas, e o número de série de cada partição aumenta de 0 e as mensagens estão em ordem;

Existem vários segmentos (xxx.index, xxx.log) no arquivo de partição;

O tamanho no arquivo de segmento é o mesmo que o tamanho do arquivo de configuração e pode ser modificado de acordo com os requisitos. O padrão é 1g.
Se o tamanho for maior que 1g, um novo segmento será rolado e nomeado após o deslocamento de a última mensagem do segmento anterior.

3.24. Mecanismo de ACK de Kafka

request.required.acks tem três valores 0 1 -1

  • 0: O produtor não vai esperar pelo ack do corretor. Este atraso é o menor, mas a garantia de armazenamento é a mais fraca. Quando o servidor travar, os dados serão perdidos

  • 1: O servidor aguardará o valor do ACK, e a cópia do líder enviará um ACK após confirmar que recebeu a mensagem, mas se o líder desligar, ele não garante se a cópia foi concluída para o novo líder, o que também causará perda de dados

  • -1: Também na base de 1, o servidor aguardará que todas as cópias do seguidor recebam os dados antes de receber o ACK enviado pelo líder, para que os dados não sejam perdidos

3.25. Como os consumidores Kafka consomem dados

Toda vez que um consumidor consumir dados, o consumidor registrará a posição de compensação física (offset) de consumo e, na próxima vez que consumir, continuará consumindo na última posição

3.26. Estratégia de balanceamento de carga do consumidor

Um fragmento em um grupo de consumidores corresponde a um membro consumidor, o que pode garantir que todos os membros consumidores possam acessar, se houver
muitos membros no grupo, haverá membros ociosos

3.27. Dados ordenados

Em um grupo de consumidores, seu interior é ordenado,
e o grupo de consumidores é desordenado entre grupos de consumidores

3.28. Estratégia de agrupamento de dados quando kafaka produz dados

O produtor decide em qual partição do cluster os dados são gerados

Cada mensagem está no formato (chave, valor)

A chave é enviada pelo produtor para enviar dados em

Então o produtor (chave) determina para qual partição do cluster os dados são gerados

3.29 O que significam LEO, LSO, AR, ISR e HW?

LEO : Log End Offset. Valor do offset final do log ou end offset, indicando o valor do offset da próxima mensagem a ser inserida no log. Por exemplo, se o log tiver 10 mensagens e o valor de deslocamento começar em 0, o valor de deslocamento da 10ª mensagem será 9. Neste ponto, LEO = 10.

LSO : Log Stable Offset. Este é o conceito de transações Kafka. Se você não usar transações, esse valor não existe (na verdade, ele não existe, apenas é definido como um valor sem sentido). Esse valor controla o escopo das mensagens que um consumidor transacional pode ver. Muitas vezes, é confundido com o Log Start Offset, que é o valor do log start offset, porque algumas pessoas abreviam o último como LSO, o que está errado. No Kafka, LSO refere-se ao deslocamento estável de log.

AR : Réplicas atribuídas. AR é o conjunto de réplicas alocadas quando a partição é criada após a criação do tópico e o número de réplicas é determinado pelo fator de réplica.

ISR : réplicas sincronizadas. Um conceito particularmente importante em Kafka refere-se ao conjunto de réplicas em AR que são mantidas em sincronia com o Líder. A cópia em AR pode não estar no ISR, mas a cópia líder é naturalmente incluída no ISR. Com relação ao ISR, outra pergunta comum em entrevistas é como julgar se uma cópia deve pertencer ao ISR. A base atual para julgar é se o tempo em que o LEO da réplica do Seguidor fica atrás do LEO do Líder excede o valor do parâmetro replica.lag.time.max.ms no lado do Broker. Se excedido, a réplica é removida do ISR.

HW : Valor de marca d'água alta (marca d'água alta). Este é um campo importante que controla o intervalo de mensagens que um consumidor pode ler. Um consumidor normal só pode "ver" todas as mensagens na cópia líder entre Log Start Offset e HW (exclusivo). As mensagens acima do nível da água são invisíveis para os consumidores.

3.30. Kafka pode deletar mensagens manualmente?

Na verdade, o Kafka não exige que os usuários excluam mensagens manualmente. Ele próprio fornece uma política de retenção que exclui automaticamente as mensagens expiradas. Claro, ele suporta a exclusão manual de mensagens. Portanto, é melhor você responder a partir dessas duas dimensões.

  • Para um tópico com uma chave definida e o parâmetro cleanup.policy=compact, podemos construir uma mensagem <Key, null> e enviá-la ao Broker e excluir a mensagem da chave contando com as funções fornecidas pelo componente Log Cleaner.
  • Para tópicos comuns, podemos usar o comando kafka-delete-records ou escrever um programa para chamar o método Admin.deleteRecords para excluir mensagens. Esses dois métodos levam ao mesmo objetivo.A camada inferior chama o método deleteRecords do Admin para excluir indiretamente as mensagens aumentando o valor do Log Start Offset da partição.

3.31 Para que serve __consumer_offsets?

Este é um tópico interno, e as informações públicas do site oficial raramente são abordadas. Portanto, acho que esta questão pertence à categoria de entrevistador exibindo habilidades. Você deve ter cuidado com os pontos de teste aqui: existem 3 pontos de conhecimento importantes neste tópico e você deve responder a todos eles para parecer muito familiarizado com este conhecimento.

É um tópico interno, gerenciado pelo próprio Kafka sem intervenção manual. Claro, podemos criar esse tema.

Sua principal função é ser responsável por cadastrar os consumidores e salvar os valores de deslocamento. Você pode estar familiarizado com a função de salvar valores de compensação, mas, na verdade, esse tópico também é onde os metadados do consumidor são salvos. Certifique-se de responder a isso também. Além disso, os consumidores aqui geralmente se referem a grupos de consumidores e consumidores independentes, não apenas a grupos de consumidores.

O componente GroupCoordinator do Kafka fornece funções completas de gerenciamento para o tópico, incluindo criação, gravação, leitura e manutenção do líder do tópico.

3.32 Quantas estratégias de eleição de líder de partição existem?

A eleição da cópia líder da partição é totalmente transparente para o usuário e é realizada de forma independente pelo Controlador. O que você precisa responder é, em quais cenários, você precisa realizar a eleição do líder da partição. Cada cenário corresponde a uma estratégia eleitoral. Atualmente, Kafka tem quatro estratégias de eleição de líder de partição.

3.32.1, Eleição do Líder da Partição Offline

A eleição do líder precisa ser realizada sempre que uma partição ficar online. A chamada partição que fica online pode ser a criação de uma nova partição, ou pode ser que a partição anteriormente offline esteja novamente online. Este é o cenário de eleição de líder de partição mais comum.

3.32.2. Reatribuir Eleição de Líder de Partição

Essas eleições podem ser acionadas quando você executa manualmente o comando kafka-reassign-partitions ou chama o método alterPartitionReassignments do administrador para executar reatribuições de cópia de partição.

Assumindo que o AR original é [1, 2, 3] e o Líder é 1, após a reatribuição da réplica, o conjunto de réplicas AR é definido como [4, 5, 6]. Obviamente, o Líder deve ser alterado e A reatribuição ocorrerá neste momento na eleição do Líder da Partição.

3.32.3, Eleição do líder PreferredReplicaPartition

Esse tipo de estratégia é ativado quando você executa manualmente o comando kafka-preferred-replica-election ou aciona automaticamente a eleição de líder preferencial. O chamado Preferred Leader refere-se à primeira réplica em AR. Por exemplo, AR é [3, 2, 1], então o Líder Preferido é 3.

3.32.4, Eleição do líder ControlledShutdownPartition

Quando um Broker desliga normalmente, todas as cópias do Líder no Broker ficarão offline, portanto, as eleições de Líder correspondentes precisam ser realizadas para as partições afetadas.

As ideias gerais desses quatro tipos de estratégias eleitorais são semelhantes, ou seja, selecionar a primeira réplica no ISR do AR como o novo Líder. Claro, existem pequenas diferenças nas estratégias individuais.

3.33 Onde as eleições são exigidas em Kafka? Quais são as estratégias eleitorais nesses lugares?

Eleição do Controlador

  • A eleição do Controlador Kafka é realizada contando com o Zookeeper. Qual corretor no cluster Kafka pode criar com sucesso o nó/controlador temporário (EPHEMERAL) pode se tornar o Controlador Kafka.

Eleição do líder da partição

  • https://www.jianshu.com/p/1f02328a4f2e

eleições relacionadas ao consumidor

  • O coordenador do grupo GroupCoordinator precisa eleger um líder de grupo de consumidores para os consumidores do grupo de consumidores.O algoritmo desta eleição também é muito simples, sendo analisado em duas situações. Se não houver líder no grupo de consumo, o primeiro consumidor a entrar no grupo de consumo é o líder do grupo de consumo. Se em algum momento o consumidor líder sair do grupo de consumidores por algum motivo, um novo líder será reeleito.

3.34 Em quais cenários do Kafka é utilizada cópia zero (Zero Copy)?

Zero Copy é uma pergunta avançada que é particularmente fácil de fazer. No Kafka, existem dois locais onde o Zero Copy é usado: o índice baseado em mmap e o TransportLayer usado para ler e gravar arquivos de log.

Deixe-me falar sobre o primeiro primeiro. Os índices são baseados em MappedByteBuffer, ou seja, o modo usuário e o modo kernel compartilham o buffer de dados do modo kernel.Neste momento, os dados não precisam ser copiados para o espaço do modo usuário. No entanto, embora o mmap evite cópias desnecessárias, não necessariamente garante alto desempenho. Em diferentes sistemas operacionais, os custos de criação e destruição do mmap podem ser diferentes. A alta sobrecarga de criação e destruição compensará os benefícios de desempenho trazidos pelo Zero Copy. Devido a essa incerteza, no Kafka, apenas o índice usa mmap e o log principal não usa o mecanismo mmap.

Vamos falar sobre o segundo. TransportLayer é a interface da camada de transporte do Kafka. Uma de suas classes de implementação usa o método transferTo de FileChannel. A camada inferior deste método usa sendfile para implementar Zero Copy. Para o Kafka, se o canal de I/O usa PLAINTEXT comum, o Kafka pode usar o recurso Zero Copy para enviar diretamente os dados no cache da página para o buffer da placa de rede, evitando várias cópias no meio. Pelo contrário, se o SSL estiver ativado no canal de E/S, o Kafka não poderá aproveitar o recurso Zero Copy.

3.35 Por que Kafka não oferece suporte à separação de leitura e gravação?

Esta questão examina seu pensamento sobre o modelo Líder/Seguidor.

O modelo Líder/Seguidor não estipula que as réplicas do Seguidor não possam fornecer serviços de leitura externos. Muitos frameworks permitem isso, mas Kafka inicialmente adotou o método de permitir que o Líder forneça serviços uniformemente para evitar o problema de inconsistência.

Desde o Kafka 2.4, o Kafka fornece separação limitada de leitura e gravação, ou seja, as réplicas do seguidor podem fornecer serviços de leitura externos.

Depois de dizer isso, você pode explicar o motivo pelo qual a versão anterior não oferece suporte à separação de leitura e gravação:

  • Cenário não se aplica. A separação de leitura e gravação é adequada para cenários com carga de leitura pesada e operações de gravação relativamente pouco frequentes, mas Kafka não pertence a esses cenários.
  • mecanismo de sincronização. Kafka usa o método PULL para realizar a sincronização do seguidor, portanto, há uma janela de inconsistência entre o seguidor e o líder. Se a cópia do Seguidor puder ser lida, é necessário lidar com o problema de atraso da mensagem (Lagging).

3.36. Como sintonizar Kafka?

Para Kafka, os objetivos comuns de otimização são taxa de transferência, latência, durabilidade e disponibilidade. As ideias de otimização em cada direção são diferentes, ou mesmo opostas.

Depois de determinar o objetivo, também é necessário esclarecer as dimensões da otimização. Alguns ajustes são uma ideia de otimização geral, como a otimização do sistema operacional, JVM etc.; alguns são direcionados, como a otimização do TPS do Kafka. Precisamos considerar de 3 direções

  • Lado do produtor : aumente batch.size, linger.ms, habilite a compactação, desative a repetição, etc.
  • Lado do corretor : aumente num.replica.fetchers, melhore a sincronização do Seguidor TPS, evite o Broker Full GC, etc.
  • Consumidor : aumenta fetch.min.bytes, etc.

3.37 O que acontece com o Kafka quando ocorre o particionamento de rede no controlador?

Como o Controlador enviará três tipos de solicitações ao Broker, a saber, LeaderAndIsrRequest, StopReplicaRequest e UpdateMetadataRequest, uma vez que ocorra uma partição de rede, essas solicitações não conseguirão chegar ao lado do Broker sem problemas. Isso afetará a sincronização de informações das operações de criação, modificação e exclusão do tópico, e o cluster parece estar congelado, incapaz de perceber todas as operações subsequentes. Portanto, as partições de rede geralmente são problemas muito sérios que precisam ser corrigidos rapidamente.

3.38 Por que o Java Consumer usa um único thread para obter mensagens?

Java Consumer é um design de dois segmentos. Um thread é o thread principal do usuário, responsável por obter mensagens; o outro thread é o thread de pulsação, responsável por relatar o status de sobrevivência dos consumidores ao Kafka. Colocar a pulsação em um thread dedicado pode efetivamente evitar a situação de "morte falsa" que é considerada offline devido à baixa velocidade de processamento de mensagens.

O design de aquisição de mensagem de thread único pode evitar métodos de aquisição de mensagem de bloqueio. O método de polling de thread único é fácil de implementar assíncrono e sem bloqueio, o que facilita a expansão dos consumidores em operadores que oferecem suporte ao processamento de fluxo em tempo real. Porque muitos operadores de processamento de fluxo em tempo real não podem bloquear. Outro benefício possível é que simplifica o desenvolvimento de código. O código que interage com vários threads é muito propenso a erros.

3.39. Descreva resumidamente o processo completo de sincronização da mensagem de cópia do seguidor

Primeiro, o seguidor envia a solicitação FETCH ao líder. Em seguida, o líder lerá os dados da mensagem no arquivo de log subjacente e atualizará o valor LEO da cópia do seguidor em sua memória para o valor fetchOffset na solicitação FETCH. Por fim, tente atualizar o valor da marca d'água alta da partição. Após o seguidor receber a resposta FETCH, ele gravará a mensagem no log subjacente e, em seguida, atualizará os valores LEO e HW.

O tempo de atualização do HW do Líder e do Seguidor é diferente, e a atualização do HW do Seguidor sempre fica atrás do HW do Líder. Essa incompatibilidade no tempo é responsável por todos os tipos de inconsistências.

3.40 Simplificando: como o Kafka atinge um alto rendimento?

Kafka é um sistema de mensagens distribuídas que precisa processar mensagens massivas. O projeto de Kafka é gravar todas as mensagens em discos rígidos com baixa velocidade e grande capacidade em troca de maior capacidade de armazenamento. Mas, na verdade, usar discos rígidos não traz perda excessiva de desempenho . Kafka usa principalmente os seguintes métodos para obter uma taxa de transferência ultra-alta:

  • Leitura e escrita sequencial;

  • cópia zero

  • segmentação de arquivo

  • envio em lote

  • compressão de dados.

Especificamente:

A leitura e gravação de arquivos dependem do cache de página do sistema de arquivos do sistema operacional em vez de armazenar dados em cache dentro da JVM, usando o sistema operacional para armazenar em cache, e a taxa de utilização da memória é alta

tecnologia sendfile (cópia zero), evitando o processo de quatro etapas da rede tradicional IO

Suporta compactação de ponta a ponta

E/S sequencial e mensagens get e put de tempo constante

A partição pode escalar bem e fornecer alto processamento simultâneo

3.41 Como Kafka atinge milhões de gravações simultâneas ultra-altas por segundo?

Kafka é um middleware de mensagens de alto rendimento, baixa latência, alta simultaneidade e alto desempenho amplamente utilizado no campo de big data. Um cluster Kafka bem configurado pode atingir centenas de milhares ou milhões de gravações simultâneas ultra-altas por segundo.

3.41.1, tecnologia de cache de página + gravação sequencial em disco

Em primeiro lugar, o Kafka gravará no disco toda vez que receber dados, conforme mostra a figura a seguir:
insira a descrição da imagem aqui

Portanto, aqui não podemos deixar de ter uma pergunta. Se os dados são armazenados no disco e os dados são freqüentemente gravados no arquivo de disco, o desempenho será ruim? Todos devem pensar que o desempenho de gravação do disco é extremamente ruim.

É isso mesmo, se for tão simples quanto a imagem acima, então o desempenho é realmente relativamente ruim.

Mas, na verdade, o Kafka tem um design excelente e excelente aqui, apenas para garantir o desempenho da gravação de dados. Em primeiro lugar, o Kafka implementa a gravação de arquivos com base no cache da página do sistema operacional.

O próprio sistema operacional possui uma camada de cache, chamada Page Cache, que é um cache na memória, também podemos chamar de OS Cache, que significa o cache gerenciado pelo próprio sistema operacional.

Ao gravar um arquivo em disco, você pode gravá-lo diretamente no Cache do SO, ou seja, apenas gravá-lo na memória e, em seguida, o sistema operacional decide quando realmente liberar os dados do Cache do SO no arquivo do disco.

Apenas esta etapa pode melhorar muito o desempenho da gravação de arquivos em disco, porque, na verdade, isso equivale a gravar na memória, não no disco. Veja a figura a seguir:
insira a descrição da imagem aqui

Então o outro é quando o Kafka grava os dados, um ponto muito crítico, eles são gravados na ordem do disco.

Ou seja, apenas anexando dados ao final do arquivo, não modificando dados em locais aleatórios no arquivo.

Discos mecânicos comuns têm desempenho extremamente ruim se você gravar aleatoriamente, ou seja, você pode encontrar um determinado local no arquivo para gravar dados.

Mas se você gravar dados sequencialmente anexando ao final do arquivo, o desempenho dessa gravação sequencial de disco pode ser basicamente semelhante ao desempenho da gravação na própria memória.

Portanto, todos sabem que na figura acima, quando Kafka grava dados, por um lado, ele grava dados com base no Page Cache no nível do SO, então o desempenho é muito alto e a essência é gravar na memória.

Outra é que ele usa gravação sequencial em disco, portanto, mesmo quando os dados são liberados no disco, o desempenho é extremamente alto, o que é semelhante à gravação na memória.

Com base nos dois pontos acima, Kafka atinge desempenho ultra-alto para gravar dados. Então pense bem, se Kafka leva 1 milissegundo para escrever um dado, é possível escrever 1000 dados por segundo?

Mas se o desempenho do Kafka for extremamente alto, leva apenas 0,01 milissegundos para gravar um dado? Então, 100.000 dados podem ser gravados por segundo?

Portanto, o ponto principal para garantir que dezenas de milhares ou mesmo centenas de milhares de dados sejam gravados por segundo é melhorar o desempenho de cada gravação de dados o máximo possível, para que mais dados possam ser gravados em uma unidade de tempo e taxa de transferência pode ser melhorado. .

3.41.2. Tecnologia de cópia zero

Depois de falar sobre a escrita, vamos falar sobre o consumo.

Todos devem saber que muitas vezes precisamos consumir dados do Kafka, então, ao consumir, na verdade precisamos ler um pedaço de dados do arquivo de disco do Kafka e enviá-lo para os consumidores downstream, conforme mostrado na figura a seguir:

insira a descrição da imagem aqui

Portanto, se os dados são frequentemente lidos do disco e enviados aos consumidores, onde está o gargalo de desempenho?

Supondo que se o Kafka não fizer nenhuma otimização, é muito simples ler os dados do disco e enviá-los para os consumidores downstream, então o processo geral é o seguinte:

Verifique primeiro se os dados a serem lidos estão no Cache do SO, caso contrário, leia os dados do arquivo em disco e coloque-os no Cache do SO.

Em seguida, copie os dados do cache do sistema operacional do sistema operacional para o cache do processo do aplicativo e, em seguida, copie os dados do cache do processo do aplicativo para o cache do soquete no nível do sistema operacional.

Por fim, os dados são extraídos do cache do Socket e enviados para a placa de rede e, por fim, enviados para o consumidor downstream.

Todo o processo é mostrado na figura abaixo:
insira a descrição da imagem aqui

Se você observar a imagem acima, poderá ver claramente que existem duas cópias desnecessárias! Uma é copiada do cache do sistema operacional para o cache do processo do aplicativo e, em seguida, copiada do cache do programa aplicativo de volta para o cache de soquete do sistema operacional.

Além disso, para realizar essas duas cópias, várias trocas de contexto ocorreram no meio.Por um tempo, o programa aplicativo estava em execução e, por um tempo, o contexto mudou para o sistema operacional para execução.

Portanto, a leitura de dados dessa maneira consome mais desempenho. Para resolver esse problema, Kafka introduz a tecnologia de cópia zero ao ler dados.

Ou seja, os dados no Cache do sistema operacional são enviados diretamente para a placa de rede e depois transmitidos para os consumidores downstream, pulando duas etapas de cópia de dados no meio, e apenas um descritor será copiado no cache Socket, e nenhum os dados serão copiados para o cache do Socket.

Dê uma olhada na foto abaixo para experimentar este processo delicado:
insira a descrição da imagem aqui

Com a tecnologia de cópia zero, não há necessidade de copiar os dados do Cache do SO para o cache do aplicativo e depois copiar os dados do cache do aplicativo para o cache do Socket. Ambas as cópias são omitidas, por isso é chamada de cópia zero.

O cache Socket está apenas copiando o descritor de dados para o passado, e então os dados são enviados diretamente do Cache do SO para a placa de rede.Este processo melhora muito o desempenho da leitura dos dados do arquivo durante o consumo de dados.

E você notará que, ao ler os dados do disco, primeiro verificará se há algum na memória do cache do sistema operacional.Se houver, os dados lidos são realmente lidos diretamente da memória.

Se o cluster Kafka estiver bem ajustado, você descobrirá que uma grande quantidade de dados é gravada diretamente no Cache do SO e, em seguida, lida no Cache do SO ao ler os dados.

É equivalente ao Kafka fornecer escrita e leitura de dados com base inteiramente na memória, portanto, o desempenho geral será extremamente alto.

3.42. Por que usar kafka e por que usar fila de mensagens

Buffering e redução de pico : quando há um fluxo repentino de dados upstream, o downstream pode não ser capaz de lidar com isso ou não há máquinas suficientes no downstream para garantir a redundância. Kafka pode desempenhar um papel de buffer no meio e armazenar temporariamente as mensagens nos serviços Kafka Middle e downstream podem ser processadas lentamente em seu próprio ritmo.

Desacoplamento e escalabilidade : No início do projeto, os requisitos específicos não puderam ser determinados. A fila de mensagens pode ser usada como uma camada de interface para desacoplar importantes processos de negócios. Você só precisa cumprir o contrato e programar os dados para obter recursos de expansão. Redundância: Pode ser adotado um método um-para-muitos.Uma mensagem publicada por um produtor pode ser consumida por vários serviços assinando um tópico para uso por vários negócios não relacionados.

Robustez : A fila de mensagens pode acumular solicitações, portanto, mesmo que o negócio do consumidor morra por um curto período de tempo, isso não afetará o andamento normal do negócio principal.

Comunicação assíncrona : muitas vezes, os usuários não querem ou não precisam processar as mensagens imediatamente.
As filas de mensagens fornecem um mecanismo de processamento assíncrono que permite aos usuários colocar uma mensagem na fila sem processá-la imediatamente. Coloque quantas mensagens quiser na fila e processe-as quando necessário.

3.43 O que é o corretor em Kafka?

O Broker é o agente das mensagens. Os produtores escrevem mensagens para o tópico especificado nos Brokers. Os consumidores extraem as mensagens do tópico especificado dos Brokers e, em seguida, executam o processamento de negócios. O Broker atua como uma estação de transferência para os agentes armazenarem as mensagens no meio.

3.44. Em que circunstâncias um corretor será expulso do ISR?

O líder mantém uma lista de Réplicas que estão basicamente sincronizadas com ele. Essa lista é chamada de ISR (in-sync Replica). Cada Partição possui um ISR e é mantida dinamicamente pelo líder. Se um seguidor for mais que um líder Se estiver atrasado muito atrasado, ou não iniciar uma solicitação de replicação de dados por um determinado período de tempo, o líder irá removê-lo do ISR.

3.45 As mensagens em Kafka serão perdidas e consumidas repetidamente?

Para determinar se as mensagens Kafka são perdidas ou duplicadas, comece por dois aspectos: envio de mensagens e consumo de mensagens .

enviar mensagem

Existem duas formas de enviar mensagens Kafka: síncrona (sync) e assíncrona (assíncrona), o padrão é síncrono, que pode ser configurado através da propriedade Producer.type.

Kafka confirma a produção de mensagens configurando a propriedade request.required.acks:
0 — indica que não há confirmação se a mensagem foi recebida com sucesso;
1 — indica confirmação quando o Líder a recebe com sucesso;
-1 — indica que tanto o Líder quanto o Seguidor recebe com sucesso confirma;

Resumindo, existem 6 situações de produção de mensagem, sendo utilizada a seguinte situação para analisar o cenário de perda de mensagem:

(1) acks=0, não confirme a recepção da mensagem com o cluster Kafka, então quando a rede estiver anormal, o buffer estiver cheio, etc., a mensagem pode ser perdida; (2) acks =1, somente no modo
síncrono o Líder confirma o recebimento Se conseguir, mas desliga, a cópia não é sincronizada e os dados podem ser perdidos;

consumo de mensagens

Existem duas interfaces de consumidor para consumo de mensagens Kafka, API de baixo nível e API de alto nível: API de baixo nível
: os consumidores mantêm seus próprios equivalentes de deslocamento, que podem obter controle total sobre Kafka;
API de alto nível: encapsula o gerenciamento de parição e compensação são fáceis de usar;

Se você usar a interface de alto nível API de alto nível, pode haver um problema que quando o consumidor de mensagem retira a mensagem do cluster e envia um novo valor de deslocamento de mensagem, ele desliga antes do consumo, então A notícia de que o anterior o consumo não foi bem-sucedido desaparecerá "estranhamente" quando o próximo consumo for feito;

Solução:

Para perda de mensagem:
no modo síncrono, o mecanismo de confirmação é definido como -1, ou seja, a mensagem é escrita para o Líder e o Seguidor antes de confirmar que a mensagem foi enviada com sucesso; no modo assíncrono, para evitar que
o buffer seja cheio, você pode definir bloqueio ilimitado no arquivo de configuração Timeout, quando o buffer
está cheio, o produtor é sempre bloqueado;

Para repetição de mensagem: salve o identificador único da mensagem em um meio externo e julgue se ela foi processada cada vez que for consumida.

3.46 Como Kafka reflete a sequência de mensagens?


As mensagens em cada partição do Kafka são ordenadas quando são escritas, e quando consumidas, cada partição só pode ser consumida por um consumidor em cada grupo, o que garante que as mensagens também sejam ordenadas quando consumidas. Não é garantido que todo o tópico esteja em ordem. Se, para garantir toda a ordem do tópico, ajuste a partição para 1

4. RocketMQ

4.1 Como selecionar vários MQs?

RabbitMQ
é desenvolvido em erlang, e o suporte para acúmulo de mensagens não é bom. Quando um grande número de mensagens é acumulado, o desempenho do RabbitMQ cairá drasticamente. Dezenas de milhares a centenas de milhares de mensagens podem ser processadas por segundo.

O desenvolvimento Java RocketMQ
, orientado para clustering da Internet, possui funções ricas e fez muitas otimizações para o atraso de resposta dos negócios on-line. Na maioria dos casos, pode atingir uma resposta em nível de milissegundos e pode processar centenas de milhares de mensagens por segundo .

Desenvolvimento Kafka
Scala, orientado a log, rico em recursos, o mais alto desempenho. Quando em seu cenário de negócios, o número de mensagens por segundo não for tão grande, o atraso do Kafka será relativamente alto. Portanto, Kafka não é adequado para cenários de negócios online.

O desenvolvimento em Java ActiveMQ
é simples e estável, e seu desempenho não é tão bom quanto os três anteriores. Não recomendado.

4.2 Quais são os componentes (funções) do RocketMQ?

O servidor de nomes
não tem estado e possui uma lista dinâmica; essa também é uma das diferenças importantes do zookeeper. zookeeper é stateful.

Produtor
O produtor da mensagem é responsável por enviar mensagens ao Broker.

Broker
é o próprio MQ, responsável por enviar e receber mensagens, mensagens persistentes, etc.

O consumidor da mensagem do consumidor
é responsável por extrair as mensagens do Broker para consumo e acessá-las após o consumo.

4.3 Quantos modos de consumo o RocketMQ possui?

consumo de cluster

Uma mensagem só será consumida por um consumidor no mesmo grupo.
Quando vários grupos consomem um tópico ao mesmo tempo, cada grupo terá um consumidor que consome os dados

consumo de transmissão

A mensagem será consumida para cada instância de consumidor em um grupo de consumidores. Mesmo que esses consumidores pertençam ao mesmo grupo de consumidores, a mensagem será consumida uma vez por cada consumidor do grupo de consumidores.

4.4 Como resolver o consumo repetido de mensagens?

Motivos: Em
circunstâncias normais, após o consumidor ter efetivamente consumido a mensagem, ele deve enviar um ACK para avisar ao broker que a mensagem foi consumida normalmente, e retirá-la da fila
. Por motivos de rede, o corretor pensará que a mensagem de entrada não foi consumida. Ative o mecanismo de reentrega de mensagem para reentregar a mensagem ao consumidor.

Modo de consumo: No modo CLUSTERING, a mensagem será garantida para ser consumida uma vez pelo consumidor do mesmo grupo no broker, mas será enviada várias vezes para consumidores de grupos diferentes

solução

  • Tabela de banco de dados: antes de processar a mensagem, use a chave primária da mensagem para inserir no campo com restrições na tabela
  • Mapa: você pode usar o mapa como um limite no modo autônomo e verificar se o ID da mensagem atual já existe ao consumir
  • Redis: Use bloqueios distribuídos.

4.5 Como o RocketMQ garante o consumo sequencial de mensagens?

Em primeiro lugar, múltiplas filas só podem garantir a ordem em uma única fila, e a fila é uma FIFO típica, com ordem natural. O consumo simultâneo por múltiplas filas não pode garantir absolutamente a ordem das mensagens.
Você pode usar o mesmo tópico, a mesma QUEUE, um thread para enviar mensagens ao enviar mensagens e um thread para consumir mensagens em uma fila ao consumir.

4.6 Como o RocketMQ garante que as mensagens não sejam perdidas?

Lado do produtor

Use send() para enviar mensagens de forma síncrona e o resultado do envio é percebido de forma síncrona.
Você pode tentar novamente após enviar uma falha, defina o número de tentativas. O padrão é 3 vezes.

No lado do Broker
, modifique a estratégia de brushing de disco para brushing de disco síncrono. Por padrão, é assíncrono.
implantação de cluster

Do lado do consumidor,
a confirmação manual é realizada após o consumo total ser normal

4.7. Em quais funções o RocketMQ consiste?

  • Produtor : Responsável por gerar as mensagens, o produtor envia as mensagens geradas pelo sistema aplicativo de negócios para o servidor de mensagens.

  • Consumidor (Consumer) : Responsável por consumir mensagens, o consumidor extrai informações do servidor de mensagens e as insere no aplicativo do usuário.

  • Servidor de mensagens (Broker) : É um centro de armazenamento de mensagens, cuja função principal é receber e armazenar mensagens do Produtor, e o Consumidor obtém as mensagens daqui.

  • Servidor de nomes (NameServer) : usado para salvar tópicos relacionados ao corretor e outras metainformações e fornecer produtor e consumidor para encontrar informações do corretor.

4.8, Processo de execução do RocketMQ

  • Inicie o Namesrv e o Namesrv escutará a porta depois que ela for ativada, esperando que o Broker, Producer e Consumer se conectem, o que é equivalente a um centro de controle de roteamento.

  • O Broker inicia, mantém conexões longas com todos os Namesrv e envia pacotes de heartbeat regularmente.

  • Antes de enviar e receber mensagens, crie um tópico primeiro. Ao criar um Tópico, você precisa especificar em quais Brokers o Tópico será armazenado. Também é possível criar um tópico automaticamente ao enviar uma mensagem.

  • Os produtores enviam mensagens.

  • O consumidor consome mensagens.

4.9. Por favor, conte-nos sobre sua compreensão do Produtor?

  • Obtenha o relacionamento de mapeamento do Topic-Broker.

    • Quando o produtor é iniciado, ele também precisa especificar o endereço de Namesrv e selecionar um do cluster Namesrv para estabelecer uma conexão persistente.

    • O produtor obtém o relacionamento de mapeamento entre Topic e Broker do Namesrv a cada 30 segundos e o atualiza na memória local. Em seguida, estabeleça uma conexão longa com todos os Brokers envolvidos no Tópico e envie um heartbeat a cada 30 segundos.

  • Balanceamento de carga no lado do produtor.

    • Quando o produtor enviar, ele irá pesquisar automaticamente todos os corretores atualmente enviáveis.Se uma mensagem for enviada com sucesso, ela será enviada por outro corretor na próxima vez, de modo que a mensagem caia em todos os corretores em média.

4.10 Fale-me sobre sua compreensão do Consumidor?

  • Obtenha o relacionamento de mapeamento do Topic-Broker.

    • Quando o Consumer é iniciado, ele precisa especificar o endereço Namesrv e estabelecer uma longa conexão com um dos Namesrvs. O consumidor obtém o status da fila mais recente de todos os tópicos do Namesrv a cada 30 segundos,

    • Consumidor e Broker são conexões de longo prazo e enviarão informações de pulsação para o Broker a cada 30 segundos.

  • Balanceamento de carga no lado do consumidor. De acordo com os diferentes padrões de consumo dos consumidores, os métodos de balanceamento de carga também são diferentes.

4.11 Quantos padrões de consumo existem para os consumidores?

Existem dois modos de consumo do consumidor: consumo de cluster e consumo de transmissão.

  • consumo de cluster

    • Um padrão de consumo dos consumidores. Cada instância de Consumer em um Consumer Group é alocada para consumir mensagens, ou seja, uma mensagem só será entregue a uma instância em um Consumer Group.
  • consumo de transmissão

    • Um padrão de consumo dos consumidores. A mensagem será entregue a cada instância de Consumidor em um Grupo de Consumidores. Ou seja, mesmo que esses Consumers pertençam ao mesmo Consumer Group, a mensagem será consumida uma vez por cada Consumer do Consumer Group.

4.12 Quantas formas existem para o consumidor obter notícias?

Existem dois modos para os consumidores obterem mensagens: modo push e modo pull.

  • PushConsumer

    • Consumidores no modo push (embora o RocketMQ use pesquisas longas). As mensagens podem ser consumidas em tempo hábil. É muito simples de usar e manipulou internamente vários cenários, como consumo de pool de threads, controle de fluxo, balanceamento de carga, tratamento de exceções e assim por diante.
  • PullConsumer

    • Um consumidor no modo pull. O aplicativo controla ativamente o tempo de puxar, como puxar, como consumir, etc. A iniciativa é maior. Mas lide com os vários cenários você mesmo.

4.13 O que é uma mensagem agendada? Como conseguir?

Mensagem temporizada significa que após a mensagem ser enviada ao Broker, ela não pode ser consumida pelo Consumidor imediatamente, mas somente em um momento específico ou após aguardar um horário específico.

4.14 Como o RocketMQ implementa transações distribuídas?

  • O produtor envia uma meia mensagem ao servidor MQ.
  • Depois que a meia mensagem é enviada com sucesso, o servidor MQ retorna uma mensagem de confirmação ao produtor.
  • Os produtores começam a executar transações locais.
  • Envie uma mensagem de commit ou rollback para o MQ Server de acordo com o resultado da execução da transação local (UNKNOW, commit, rollback).
  • Se a mensagem de confirmação/reversão for perdida (possivelmente devido a condições anormais causadas por anormalidade da rede, tempo de inatividade repentino do produtor, etc.), o servidor MQ enviará uma mensagem de verificação para cada produtor no mesmo grupo para obter o status da transação.
  • Verifique o status da transação local do produtor.
  • Os produtores enviam mensagens de commit/rollback com base no estado da transação local.
  • O servidor MQ descartará a mensagem revertida, mas a mensagem enviada (meia mensagem com confirmação secundária) será entregue ao consumidor para consumo.

Half Message : Pré-processa a mensagem. Quando o broker receber tal mensagem, ela será armazenada na fila de consumo de mensagens de RMQ_SYS_TRANS_HALF_TOPIC

Verifique o status da transação : Broker iniciará uma tarefa agendada para consumir as mensagens na fila RMQ_SYS_TRANS_HALF_TOPIC. Cada vez que a tarefa for executada, ele confirmará o status de execução da transação (commit, rollback, desconhecido) para o remetente da mensagem. Se for desconhecido , o Corretor ligará periodicamente em cheque novamente.

Timeout : Se o número de checkbacks for excedido, a mensagem será revertida por padrão.
Ou seja, ele não entrou na fila do tópico, mas usou uma fila temporária para armazenar a chamada meia mensagem, e a meia mensagem foi realmente transferida para a fila no tópico após a confirmação da transação.

4.15 Como lidar com o acúmulo de mensagens no RocketMQ?

  • Se você pode adicionar consumidores para resolver, adicione o volume de dados dos consumidores
  • Se houver fila, mas houver muitos consumidores. Você pode usar para preparar um tópico temporário, criar algumas filas ao mesmo tempo e criar um consumidor temporário para transferir essas mensagens para o tópico para os consumidores consumirem.

Acho que você gosta

Origin blog.csdn.net/shuai_h/article/details/128993928
Recomendado
Clasificación