Olá pessoal, eu me chamo Ronaldo Lenhelles e nessa aula eu vou mostrar para vocês o que são produtores, o que são consumidores, tópicos, partições e suas principais linguagens e drivers direcionados ao Kafka. Então aqui eu vou passar um overview sobre cada um desses conceitos para que vocês possam entender e a gente consiga em futuras aulas mais avançadas configurar do jeito correto e implementar do jeito correto. Bom, primeiro é importante entender o que são tópicos e partições. Tópicos são unidades lógicas. Então, quando você ouvir falar de tópico, nada mais é do que uma unidade lógica para dividir as mensagens no Kafka. E a unidade física são partições. Então, fazendo uma analogia aqui com o banco de dados é como se o tópico ele fosse a esquema e as partições fossem as tabelas dentro do esquema tá pensando que fisicamente o que você tem no disco são partições então o que eu quero dizer é se você abrir um disco onde estão os dados do Kafka, você vai encontrar as partições lá, que é fisicamente o que existe no disco. Um tópico pode ter milhares de partições. Então, aqui nesse desenho eu coloquei só três partições para um tópico, mas, dependendo do caso, você pode ter um tópico com milhares de partições. As partições as partições garantem escalabilidade então quando você quer escalar o que vai te ajudar a escalar são as partições vocês vão já entender porque quando a gente falar de consumidores tá mas fica fica em mente que quando você quer escalar quando você quer aumentar a vazão de consumo do seu tópico você tem que ter mais partição ele segue o princípio de fifo né first in first out significa que a primeira mensagem que chegou que a 0 é a primeira que vai sair então por padrão quando o consumidor vai começar a consumir aquela mensagem sempre começa da primeira que entrou, que é a zero. Claro, ele pode muito bem pular para alguma específica, mas por padrão ele já começa na zero. Cada mensagem desse tópico, ela possui sempre três atributos. Ela possui o valor, que é realmente o conteúdo da mensagem é aqui que é uma chave que identifica a mensagem e o header que pode ser qualquer valor que você desejar o correlation id o timestamp etc tá a mensagem como é que é a mensagem ela entregue como eu falei a mensagem, como é que a mensagem é entregue? Como eu falei, a mensagem é entregue fisicamente em uma partição E como é que a gente decide qual partição? A partição é baseada na hash da key Então, imagina que a sua key é o CPF Baseado em um hash que é calculado nesse CPF O Kafka vai entregar essa mensagem da partição correta significa que toda mensagem que tiver o mesmo CPF vai ser entregue sempre da mesma partição isso é importante você ficar atento porque como eu falei, como fisicamente uma partição ela está em um nó se você colocar um milhão de mensagens com o mesmo cpf aquela parte ela vai estar sobrecarregada enquanto que se você botar apenas uma mensagem com cpf novo você vai ter uma partição com um milhão de mensagens e outra partição com uma mensagem apenas tá é importante ficar atento aí ao balanceamento correto das partições e daqui tá as partições elas são redundantes significa se você olhar nesse desenho você vai perceber que a gente tem aqui o tópico A com duas partições. A partição 0 e a partição 1. A partição 0 é amarela e a partição 1 é vermelha. A partição 0 tem uma estrela aqui no broker 202. Significa que esse cara é o líder. Então o broker 202 é o líder da partição 0. E o broker 203 é o seguidor, ele é o líder da partição 0 e o broker33 é o seguidor, é o follower da partição 0, significa que toda vez que eu produzir uma mensagem para a partição 0 essa mesma mensagem vai ser replicada para a partição 0 do broker33 certo? porque ele é o seguidor ele é o follower a mesma coisa acontece com a partição 1 só que a partição 1 na verdade o líder agora é o 203 não mais o 202 e o follower é o 202 se vocês lembrarem eu falei em aulas passadas Sobre quem gerencia esse líder e o follower É o Zookeeper, esse é barano Então o Zookeeper vai dizer quem é o líder e quem é o follower Tá certo? E é por isso que a partição é redundante Porque se o broker 202 cair A mesma mensagem, ela provavelmente E eu digo provavelmente porque isso depende de configurações ela vai estar presente da do broker 203 também tá e agora falando um pouco de produtor e a gente fala de produtor, primeiramente, como o nome já diz, ele é responsável por produzir a mensagem da partição. Então ele produz exatamente uma partição de um tópico, como eu falei. Se aquele tópico tem N partições, ele vai produzir em uma ou várias partições específicas. específicas o broker é muito importante desculpa o produtor é muito importante definir que ele tem uma propriedade chamada ACK que significa knowledge em inglês que nada mais é do que o carimbo de recebimento da mensagem então quando você manda mensagem para o broker quando e como você quer receber ela tá esse carimbo de que a mensagem então quando você manda mensagem para o broker quando e como você quer receber ela tá esse carimbo de que a mensagem foi gravada a primeira configuração é zero seja que você não quer receber o carimbo você não quer receber nenhum tipo de resposta do broker dizendo que aquela mensagem foi gravada então fire forget você mudou a mensagem e segue vinda. Você não quer saber se ela foi gravada ou não, você pode perder ela. Então, lembrando, quando você coloca o ACK 0, você está assumindo que você pode perder a mensagem. Não é um problema. Quando você coloca o ACK1 Significa que você precisa Que a mensagem seja gravada Então você vai esperar Essa mensagem ser gravada No líder Então lembra que eu falei que no Kafka A gente tem O cluster Onde eu tenho vários nós Então você tem o nó 1, nó 2 dois ou três por exemplo e nesse caso para essa partição preço tópico o dó é o líder quando você coloca ck um você espera que esse broker e se não ele responda que gravou ok é isso ele gravou você vai embora e continua a vida você não espera os outros brokers como assim esperar os outros brokers porque lembra que eu falei há alguns minutos atrás que a partição é replicada e é isso depende de algumas configurações que a gente vai ver em aulas mais pra frente. Mas assim, cada mensagem pode ser replicada para outros brokers. Quando você coloca a CK1, você não quer esperar a réplica. Você só quer que o líder receba, que é para quem você está efetivamente mandando, e ele grave no disco. Acabou. Você não não quer esperar réplica para os outros brokers e quando você coloca a secar ou você quer esperar que todos os brokers receba essa mensagem como assim você continua mandando para o líder internamente o cápita vai replicar essa mensagem para os outros brokers e apenas quando essa mensagem estiver nos outros brokers você vai receber o ACK, que é o OK. Lembra que eu falei que é o carimbo de retorno, né? Então é o OK dizendo que a mensagem foi gravada em todos os brokers. Existe uma configuração chamada ME INSYNC REPLICA que diz exatamente a quantidade de bruxas que você quer esperar se você tiver 20 blocos você pode querer esperar só por quatro e ver espera pelos 20 né a gente também vai ver em aulas um pouco mais avançadas como configurar isso como isso funciona junto com o fator de replicação etc por agora eu quero que vocês entendam que o produtor ele tem basicamente três tipos de configuração é não quero esperar nada nenhum tipo de resposta que era apenas a resposta do líder eu quero a resposta de todos os blocos tá era resposta na verdade de que a mensagem foi replicada em todos os brokers essa estratégia é muito importante para você entender se você pode ou não perder mensagem e aí falando de consumidor se a gente olhar aqui no desenho a primeira coisa que a gente vê é que o consumidor é distribuído logicamente e consuma grupo está grupo de consumidores e isso não é só para deixar o carro ficar bonito não tá tem um propósito e o propósito é que cada consumer cada consumidor dentro do consumo grupo dentro do consumer group ele só pode consumir é só pode receber a mesma mensagem da mesma partição uma única vez ficou confuso vou repetir de outra forma tá imagina se chegou a mensagem oi da partição 0 tá essa mensagem oi da partição 0 ou ela vai chegar no consumer 1 ou no consumer 2 desse consumer group 1 ela nunca vai chegar para o consumir 1 e para o consumer 2 ao mesmo tempo ou em tempo diferente não vai chegar ela não é duplicada dentro do mesmo consumo grupo ela é única dentro do mesmo consumo grupo significa que entre os consumidores grupos ela não é única então essa mesma mensagem oi ela pode chegar para o consumidor e para o consumo é, porque eles estão em consumer group separados. Então, quando você garantir unicidade, ou seja, aquela mensagem não vai ser duplicada para a sua aplicação, você tem que colocar todas as instâncias da sua aplicação no mesmo consumer group. E aí você está garantindo que o Kafka não vai mandar aquela mensagem repetida para várias instâncias da sua aplicação outra coisa importante é que eu tenho uma ligação um para 1 do consumidor de um consumer group com uma partição. Significa dizer que, para uma mesma partição, eu não posso ter o consumer 1 e o consumer 2 do consumer group 1. Mas eu posso ter o consumer 1 e o consumer 3, porque eles são de consumer group separados. Então, de novo, por uma mesma partição, eu só posso ter um consumer de um mesmo consumer group. Então, assim, diferentes consumer groups, ok. Eu posso ter vários consumidores mas do mesmo consumidor grupo apenas um consumo beleza e o que o que que é esse consumo era final e consumir afinal se traduzir a sua aplicação então se você tá desenvolvendo uma aplicação em Java por exemplo que vai fazer o consumo dessas mensagens esse consumo era essa aplicação que tá rodando lá no cabernet sou em algum lugar que você esteja rodando sua aplicação, são as scale units. Então vamos pensar em Kubernetes, por exemplo. No Kubernetes você pode ter vários pods da sua aplicação, várias réplicas. Isso se traduz no consumer Então a sua aplicação Que tem 10 réplicas Cada uma dessas réplicas Vai ser um consumer Isso dando exemplo de Kubernetes, mas isso se aplica A qualquer tipo de Escalabilidade que você pensar Você pega uma VM Por exemplo e coloca o seu Java para rodar aí uma VM replicar essa VM em 10 você tem 10 Javas rodando uma em cada VM cada VM dessa é o consumer tá e o consumer group é o grupo de todas essas VMs unidas tá eles são um consumer group ok essas VMs unidas, tá? eles são um consumer group, ok? eu coloquei aqui o conceito de semântica que é sobre a entrega da mensagem tá? então assim quando você vai consumir uma mensagem, você tem que comitar ela comitar significa você dizer pro Kafka que você leu aquela mensagem, e o Kafka não vai te entregar aquela mensagem de novo Mais para frente, quando a gente entrar em detalhes, a gente vai ver o offset Vai ver como é que o offset se move, etc Mas agora entenda que o commit é o ato de você dizer para o Kafka Que aquela mensagem não deve ser entregue de novo para você. Existem três formas de você fazer esse commit. A primeira é antes do processamento. Significa que você recebeu a mensagem, você comitou, ou seja, você disse ao Kafka não me entregue de novo, processou, o que é processar? É gravar no banco de dados, é chamar uma API, mandar um e-mail, qualquer coisa que você precise fazer com a sua mensagem. Só que, olha o problema aqui. Nesse anteprocessamento, se você tiver algum erro nesse processamento, você perdeu a mensagem. Porque o Kafka não vai te entregar mensagem de novo certo por isso que o nome dessa semântica é at most once ou seja você vai receber do máximo essa mensagem uma vez você recebeu ela comitou processou independente do que aconteceu no processamento você não vai receber de novo então essa semântica é utilizada quando você pode perder mensagem tá eu posso perder mensagem usa a atbost once atlist once ela é aplicada depois do processamento então você não pode de forma alguma perder mensagem mas você aceita mensagem duplicada então você recebeu a mensagem processou e fez o commit percebe que aí você só vai comitar depois do processamento certo? mas imagina na seguinte situação que você recebeu a mensagem processou e na hora do commit caiu a sua aplicação. Mas você já processou. O que vai acontecer é, você vai receber a mesma mensagem de novo, porque você não comitou. E aí você vai processar de novo e vai comitar. Então nesse caso, se a gente for falar do insert na base, você vai inserir o mesmo registro duas vezes na base de dados mas você nunca vai perder mensagem e a terceira forma é o execute once que é eu não quero perder e não quero duplicar como é que funciona você recebe a mensagem, processa a mensagem e comita. Só que aí tem um detalhe, quando você recebe a mensagem, você vai ter que adicionar uma lógica a mais aí para verificar se essa mensagem já foi processada. de dados, por exemplo, você pode ter uma base de dados relacional ou não relacional que a partir do ID da mensagem você checa se você já processou ela se você já processou ela, você simplesmente descarta, vai pra próxima tá, então aqui você tem o que a gente chama de indepotência que é checar se a mensagem já foi processada antes de processar então vamos só recapitular essa última etapa aqui. Você recebe a mensagem, verifica se ela já foi processada, não foi processada, processa e comita. Então mesmo que você por algum motivo receba a mesma mensagem de novo, porque o commit não deu certo, você está checando se ela já não foi processada então você está sendo indepotente eu é tirando claro se você não quer se você não tem problema em perder mensagem eu geralmente usa a técnica a terceira técnica que é depois do processamento e com e de potência é a técnica que 90% do do jesus 15 você vai ver tá que é a mais utilizada e pra fechar aqui falar um pouco das linguagens e da igreja existem em linguagens para você conseguir produzir e consumir no Kafka eu coloquei aqui o link do Github nesse link você vai ver muitos exemplos de como produzir e consumir Java, Golang, Python, .NET, Node.js, Scala e etc. São exemplos básicos só para você entender como funciona uma produção e consumo dessa linguagem. E o outro ponto importante que eu queria deixar claro é o seguinte, a maioria das linguagens ela é escrita em cima de uma lib chamada librd kafka você vai escutar muito sobre essa lib tá essa é uma lib que tem c que se comunica com kafka então essa lib ela faz a produção e o consumo de mensagens do kafka outras linguagens como o go por exemplo ela usa essa lib para produzir e consumir. Por que, Ronaldo? Porque em vez de escrever toda a lógica, toda a comunicação TCP para falar com Kafka, produzir, consumir, comitar, eles decidiram usar essa lib que já tem toda a sua implementação de baixo nível com exceção de linguagens como Java, Scala, Clojure, Kotlin e o próprio C todas as outras usam o librd Kafka que não é uma coisa ruim, eu não estou falando que é ruim usar o librd Kafka só quero deixar bem claro para vocês que vocês vão ouvir muito falar disso quando você estiver no python no .NET que você precisa ter essa lib da sua máquina librd kafka então se você tá lá no Linux no Mac por exemplo você tem que instalar essa lib lá no seu sistema operacional para poder conseguir usar o alíin Python de comunicação com Kafka. O que se você não entender o que é isso, não vai fazer muito sentido. Poxa, mas eu estou usando o Python aqui, mas tenho que instalar o Alibin C? É, porque na verdade quem faz a comunicação é esta Alibin C. Alibin Python em Golang é um wrapper. Ela é uma administração de alto nível, para você não ter que implementar chamadas direto para o librdk, que é uma lib de baixo nível. Certo? Espero que vocês tenham gostado e até a próxima.