Oi pessoal, meu nome é Ronaldo Lanielas e eu vou mostrar para vocês como configurar e iniciar o Apache Kafka junto com o Zookeeper e usando uma interface gráfica chamada KHQ com Docker. Então, aqui na minha tela eu criei um Docker Compose YAML. Para quem não sabe o que é Docker Compose, ele nada mais é do que uma ferramenta que vai ajudar a subir vários containers como se fosse um projeto único. Então, em vez de eu ficar subindo containers separados, subindo o container do Kafka, subindo o container do Zookeeper, eu crio apenas um arquivo que funciona como se fosse um projeto e aí eu peço para essa ferramenta chamada Docker Compose subir tudo de uma vez só. E aí eu consigo manipular tudo junto. Então eu consigo parar tudo junto. Consigo ver os logs de tudo junto. Então funciona exatamente como se fosse um projeto único que é esse objetivo. Bom, aqui é o meu arquivo YAML, o link eu encurtei ele e vai aparecer aqui no vídeo, então você pode usar esse link aqui do vídeo para poder acessar esse arquivo. Ele tem uma seção chamada serviços. Essa seção chamada serviços tem todos os serviços, todos os containers que eu preciso subir. Como a gente está falando de Kafka, eu preciso primeiro ter o Zookeeper. Então lembra das outras aulas onde eu falei para vocês que o Zookeeper é obrigatório. Então a primeira coisa que eu tenho que subir é o Zookeeper. A imagem que eu estou usando é a imagem da Confluent existem diversas imagens na internet do Zookeeper mas eu optei por usar o da Confluent e etc aqui é o hostname do container e aqui é o nome do container esse aqui é opcional não é obrigatório, eu quis colocar só pra deixar explícito e aqui é a nome do container. Essa aqui é opcional, não é obrigatória, eu quis colocar só para deixar explícito. E aqui é a porta que ele vai expor. Então assim, internamente o Zookeeper vai subir na porta 2181. E eu estou expondo para o mundo, estou expondo para fora da minha rede Docker, na 2181 também. Significa que mesmo se você estiver fora do docker Você vai conseguir acessar Esse container na porta 2181 Poderia expor em outra porta Por exemplo 2183 ou etc Ainda nesse serviço aqui De Zookeeper Eu tenho duas variáveis de ambiente que são muito importantes Que é A porta que o Zookeeper vai subir que é a 2081, é a padrão e o tick time esse tick time aqui é o tempo que o Zookeeper vai fazer a verificação de metadados e algumas outras informações enfim é uma configuração interna, mas o tick time aqui é a configuração desse tempo, você na verdade pode até excluir essa varal de ambiente e deixar de usar o padrão tá não precisa quando a gente tiver falando sobre tanin etc a gente vai entrar um pouco mais no detalhe dessa parte de tick time e etc tá bom isso eu tenho o Zookeeper e agora eu vou pro Kafka. O Kafka eu chamei de broker, poderia também chamar de qualquer outra coisa, por exemplo, Kafka. A imagem eu tô usando da Confluent também. E ele depende do Zookeeper, significa que esse broker só vai subir quando o Zookeeper estiver de pé. Certo? E tô expondo ele na porta 9092 Então a porta interna, a porta que eu estou subindo no meu serviço No docker 9092, estou expondo também na mesma porta De novo, a porta de exposição pode ser diferente da porta que o serviço está rodando Então poderia ser 9094 ou qualquer outra porta se você estiver usando a 9092 na sua máquina já. Aqui a gente tem algumas configurações. Eu não vou entrar em detalhe em todas as configurações, porque a gente vai ter aulas específicas para falar de TAN em configuração do broker em detalhes. Mas algumas muito importantes aqui configuração do broker em detalhes, tá? Mas algumas muito importantes aqui são o ID do broker. Lembra que eu falei para vocês que o Zookeeper, desculpa, o Kafka, ele funciona em modo cluster na maioria das vezes quando a gente está falando do ambiente de produção. E aí cada broker tem um ID. Então, broker 1, 2, 3, 4. Isso aqui, como a gente já tem um broker, ele é o broker1. Outra coisa importante é que cada broker fala com o Zookeeper. Então, relembrando também as aulas anteriores, quando eu falo que o broker, ele não conhece a URL do outro broker através de configuração. Ele vai no Zookeeper e o Zookeeper resolve vamos dizer essa clusterização ele que diz quem que faz parte do cluster e é por isso que o broker ele tem a URL do zookeeper é importante aqui falando de docker salientar aqui o seguinte né eu tô fazendo uma menção Ao nome do serviço Dois pontos A porta Essa porta é a porta interna Então quando você está subindo Esse serviço de Locker Compose Internamente Internamente Ele cria uma rede Como se fosse Uma subnet P tá como se fosse uma subnet tá pensa como se fosse uma subnet é com ip separados etc então esses serviços eles se comunicam entre si através dessa rede interna e é por isso que a gente consegue fazer menção do host name aqui e da porta de forma interna então por exemplo, se eu colocasse 21.8.3 aqui, eu não poderia colocar 21.8.3, continua sendo 21.8.1, porque essa é a porta de comunicação entre os containers daquele docker compose tá isso é bem importante, porque se você colocar por exemplo, localhost dos .281, não vai funcionar. Porque localhost, ele vai tentar conectar dentro do próprio container, e ainda não existe esse serviço rodando na 2.281 desse container aqui, que é o broker. Então, por isso que ele tem que fazer menção ao hostname, que é o Zookeeper. Legal. Tem algumas outras coisas aqui, como protocolo de segurança, listeners, a gente não vai falar agora sobre isso, vai ter aulas específicas para falar disso. Métrica, como o JMX também, a gente vai falar mais para frente. O AKHQ é o último aqui, ele está aqui mais para a gente conseguir ver tudo funcionando. Então, o AKHQ vai para a gente conseguir ver tudo funcionando então o AkakaCade vai ajudar a gente a não ficar só achando que está funcionando então subir o Zookeeper, subir o Kafka e agora? Como é que eu sei que realmente está funcionando? Como é que eu sei que o tópico está lá? A partição está lá? Eu posso fazer isso via linha de comando ou eu posso fazer usar uma interface gráfica Existem diversas interfaces gráficas aí Eu gosto muito dessa KHQ Ela é free e open source, tá? De novo, como eu falei pra vocês A menção, o link, a URL Pra conectar no broker É o hostname do serviço, tá? Então nada de colocar localhost alguma coisa aqui tá você vai colocar aqui o broker e a porta aí você pode perguntar putz mas essa porta aqui ela não é não deveria ser 9092 aí tem um detalhe né eu falei que eu não vou entrar em detalhe aqui sobre como funciona listener mas eu quero que você entenda é que aqui a gente tem dois listeners. Um listener que é exposto, que faz com que conexões externas consigam plugar no Kafka, e um listener que faz com que conexões internas dentro dessa network aqui do Docker, consiga plugar no Kafka. E obviamente eu vou usar a primeira opção que é que são conexões internas quando eu falo interna eu estou falando dentro desse network aqui do docker compose e o khq só vai subir se o broker estiver de pé ok? e a porta dele é 8080 então a gente vai navegar conseguir acessar via navegador Essa porta 8080 aqui Então vamos lá Eu já baixei esse arquivo Então deixa eu dar um clear aqui Se eu der um VI nele aqui agora Vocês vão perceber que é exatamente o mesmo arquivo. Então ele tem aqui o serviço, o broker e o khq. Eu simplesmente copiei e colei o que está aqui no gist. Ok, então agora eu vou subir. Como é que eu faço para subir um serviço no Docker Compose? Você vai digitar docker-compose, o comando up, que é para subir todos os serviços que estão naquele YAML, e o "-d", que é para dizer para ele rodar em background. Então, rodar em background significa que eu posso fechar o meu terminal, etc. Ele vai continuar rodando por padrão quando você não especifica nada de arquivo para ele ler ele vai procurar um arquivo chamado docker-compose.yml dentro do mesmo diretório que você está rodando o comando tá esse é o padrão Aí você pode especificar o arquivo customizado se você quiser Mas aqui a gente vai usar o padrão Então vamos dar subir Ele vai mostrar aqui que está criando os equipes Já foi criado na verdade Ele vai criar o broker1 E vai criar o khq bom para eu ver se tá tudo funcionando eu vou digitar o mesmo comando docker compose eu vou dar um ps e de novo esse comando ele tem que ser executado no mesmo diretório onde você fez o download do compose.yml para que o comando docker-compose consiga identificar aonde que está os serviços então quando eu dou um docker-compose ps ele vai mostrar aqui para mim o que que eu tenho deixa eu aumentar aqui que eu tenho 3 containers o khq, o broker e o zookeeper. Percebe que ele renomeia de acordo com o nome da pasta, etc. E aqui é interessante porque, olha só, o zookeeper ele não renomeou. Por que ele não renomeou o zookeeper? Porque eu explicitei que eu queria que o nome fosse zookeeper, tá? Mas quando eu não deixo isso explícito, como é o caso do broker, ele vai pegar o nome do meu diretório, que é a ala 04, e vai adicionar aqui um índice, que nesse caso é o primeiro container com o nome broker desse YAML. Mesma coisa para o AKHQ, eu não coloquei nome nenhum, ele vai fazer uma concatenação do nome do diretório, o nome do container e o índice aqui, que é o índice 1. Aqui ele está dizendo que está tudo up. Então, está tudo funcionando. Aqui o nome do serviço, realmente. Então, se você tiver dúvida, ah, não entendi direito como funciona esse nome do container. Está aqui o nome do serviço Que é o que tá realmente aqui no YAML No arquivo YAML Esse é o nome do serviço, tá? Broker, Zookeeper e AKHQ E aqui a gente tem o comando que ele executa Mas você pode perguntar Poxa, mas em nenhum momento Eu mandei executar esse comando. De onde é que ele tirou esse comando, né? Esse comando, ele é interno do Docker. Do Dockerfile, da imagem Docker que você está usando. Então, no caso do cpserver, que é a imagem de Kafka, da Confluent, ele executa esse comando. No caso do DockerHQ, ele executa esse comando. No caso do AKHQ, ele executa esse comando. Então, é só você saber que o Dockerfile que você está usando, que é proveniente da imagem Docker, está executando esse comando internamente. E aqui eu tenho as portas, né? Lembra que eu falei que a gente tem a porta interna do container, a porta que eu consigo acessar de fora. Então, por exemplo, aqui no caso do AKHQ, a porta interna é 8080 e a externa também é 8080 mapeado na 000. Significa que está fazendo bind em todas as interfaces da minha máquina. fazendo o bind em todas as interfaces da minha máquina, então se eu tiver múltiplas placas de rede etc, qualquer uma que for eu consigo bater na 8080 e acessar o AKHK independente de qual interface eu esteja usando, tá interface de rede, certo? mesma coisa aqui pro broker e mesma coisa pro Zookeeper bom o Zookeeper ele tem um detalhe a mais Se você olhar, ele tem outras portas Tem a 2888 e a 3888 São portas internas que o Zookeeper usa para se comunicar Quando ele está em modo cluster No nosso caso aqui Mas, percebe que essas portas aqui Elas não tem mapeamento externo Significa que se eu fizer, por exemplo, um telnet vou fazer um telnet aqui localhost na porta 2888 ele vai dar falha porque essa porta realmente, ela não está exposta na minha máquina, no meu Mac agora se eu tentar fazer o Telnet na porta 2181 Ele me conecta Então ele fala assim, legal, consegui conectar O que ele fez foi Bateu na 2181 Na minha interface de rede Da minha máquina, do meu Mac OS E fez o redirecionamento Para dentro do container Na 2181 também Então ele fez um forward aqui Da minha máquina para a máquina e fez o redirecionamento para dentro do container na 28.1 também então ele fez um forward aqui da minha máquina para a máquina para o container bom, dito tudo isso explicando um pouco de network como funciona, como é que isso se comunica se eu acessar aqui como eu falei para você localhost localhost localhost 8080 o que vocês vão perceber é que a gente tem uma interface do Kafka, como eu falei não vou entrar em detalhes a gente vai falar mais do Kafka, como eu falei não vou entrar em detalhes, a gente vai falar mais pra frente de como funciona essa interface mas resumindo a gente tem aqui os brokers então assim, os nós, o broker, a mesma coisa e nesse caso eu tenho só um que é o ID1, lembra que eu configurei lá naquele YAML que é o meu broker de ID1 então tá aqui ele, ID, aqui é o meu host ok, aqui ele tá dizendo que é o controller então esse é o cara que tá controlando todo mundo é óbvio né, se só tem um nó ele é o controller, ele é o líder, ele que faz a manipulação de partições e etc tá, eu posso clicar aqui nessa lupa e ele vai me trazer aqui algumas configurações desse nó. A gente também não vai mexer agora nessas configs. A gente vai ter, como eu falei, uma aula específica de TAN e de configuração do broker. Tem milhares de configurações aqui que a gente pode alterar para fazer T turning do broker. E o mais importante são os tópicos. Então, está zerado, não tem nenhum tópico aqui. Eu posso clicar em Create a Topic. Colocar o nome aqui, aula04. Quantas partições eu quero. Vou colocar aqui 3 partições fator de replicação então eu posso dizer aqui para quantos nós eu quero replicar essa partição então imagina assim, tenho 3 partições a partição 0 vai ser replicada para quantos nós nesse caso eu nem consigo colocar mais de 1 ele vai me dar um erro porque eu não tenho mais de um nó. Então, eu tenho um nó no meu Kafka, tá? Então, aqui nesse caso, é a quantidade de nós que eu vou replicar. A gente também vai falar disso em detalhes mais pra frente. Cleanup Policy é retenção. Então, depois desse tempo aqui, que são sete dias, tá? O que vai acontecer com as minhas mensagens que estão dentro desse tópico? Elas vão ser deletadas. Ou elas podem ser compactadas, ou deletadas e compactadas. A gente também vai falar um pouco sobre isso, mas, resumindo, deletada, ele vai realmente remover fisicamente. Compactada, ele vai manter sempre a última chave se você tiver mil mensagens com a mesma chave a última mensagem desta chave vai ser mantida então vou dar um create aqui tópico criado, não tem nenhuma mensagem tamanho zero, porque não tem nenhuma mensagem, tamanho zero, porque não tenho nenhuma mensagem, e ele está em sync, ou seja, ele está sincronizado com um broker, só tem um, então faz sentido ele estar em sync 1. Como é que eu faço para produzir uma mensagem nesse tópico aula 4? Bom, eu vou clicar nessa lupa aqui. Essa lupa vai me mostrar todas as mensagens desse tópico, não tem nada eu posso clicar em produce to topic e aqui eu tenho, se vocês lembrarem das aulas passadas eu tenho basicamente 3 campos que eu preciso preencher para montar uma mensagem a chave, posso colocar aqui 1, 2, 3, 4. Um header se eu tiver. Então vamos dizer que eu tenho um header chamado... Coloca aqui. Região. São Paulo. E a minha mensagem. A minha mensagem pode ser qualquer coisa. Pode ser um XML. Pode ser um JSON. pode ser um JSON, geralmente é um JSON dependendo do que você está gravando, ou pode ser um plain text, pode ser um Hello World, tá? Pode ser um Base64. Enfim, o que eu quero dizer é que para o Kafka, tanto faz o formato da sua mensagem, tudo vai ser gravado em binário, tá? E aqui para o nosso exemplo, eu vou simplesmente mandar um hello world plain text e vou mandar produzir quando eu mando produzir, você percebe aqui que a gente tem a mensagem, aqui da mensagem, o timestamp que horas que ela foi gravada, qual partição ela foi gravada, qual é o offset dela, quantos headers ela tem e a mensagem em si. Se eu clicar em headers aqui, se eu clicar aqui, ela volta para a mensagem e me mostra aqui o header, etc. Posso produzir um Hello World 002 aqui, por exemplo. E aí ele vai gravar de novo a mesma mensagem, na verdade, mesmo o key, mas uma outra mensagem. Na mesma partição, não sei se vocês recordam, mas nas aulas anteriores eu falei sobre o hash de partição. Então, quando você usa a mesma key aquela mensagem vai cair na mesma partição sempre se eu produzir uma nova mensagem agora eu vou chamar de 456 e pode ser exatamente a mesma mensagem só com a key diferente vou só mudar aqui para 003 para identificar que é uma outra mensagem, só com aqui diferente vou só mudar aqui para 003 para a gente identificar que é uma outra mensagem coincidentemente, essa mensagem ela caiu na mesma partição mas isso é apenas uma coincidência eu poderia gravar uma outra aqui chamar de 555 está gravando na partição 0 ainda vamos gravar uma outra aqui até na partição 0 ainda Vamos gravar uma outra aqui Até a partição mudar Colocar aqui 777 777 ela caiu numa outra partição já Certo? Então não quer dizer que Pela que ser diferente ela vai cair na outra partição ela pode ser a mesma também mas é só não diria coincidência dizer que é o cálculo do resto né a forma que o resto foi calculado ele está dizendo que vai passar 10 está a ser 0 a 2 o que é garantido é que se a mensagem tem a mesma que ela vai sempre cair na mesma partição. Então, se eu mandar a 1, 2, 3, 4 de novo, teste, eu garanto que ela vai cair na partição 0. Partição 0. Perfeito. Aí o offset, a gente vai também falar mais para frente sobre o que é offset, detalhes, etc. Mas ele nada mais é do que o índice que aquela mensagem está gravada, por partição. Então perceba aqui que na partição 0, eu começo na offset 0, então a primeira mensagem é 0, a segunda é a 1, a terceira é a 2, a quarta é a 3. E aí eu mandei uma mensagem na partição 1, que foi a 777. Essa mensagem ela caiu no offset 0, porque na partição 1 não tinha nada, então ela começou do 0. Quando eu mandei outra mensagem ela caiu na 0 de novo, na partição 0, aí o offset virou 4. Então esse offset ele nada mais é do que o índice que a mensagem se encontra por partição tá bom tem outra visualização aqui que você pode clicar em partitions e aí você consegue ver exatamente aqui quais são os offsets então na partição 0 aqui eu vou do offset 0 ao 5 na partição 1 do 0 a 1 e na partição 2 não tem nenhuma mensagem. Você consegue até ver a quantidade de bytes que tem em cada partição. E uma outra coisa interessante aqui também é, se você lembrar que eu expliquei nas aulas anteriores, cada partição tem um líder e um follower. Nesse caso aqui, como eu só tenho um nó, o líder vai ser sempre um e o follower vai ser sempre um também. É isso pessoal, espero que vocês tenham gostado e até a próxima.