# EDA e o Apache Kafka como Message Broker ![image](https://hackmd.io/_uploads/HJa59d3d6.png) - Apache Kafka se propõe a atuar na camada de implementação dos conceitos Event-driven, posicionando-se como principal orquestrador para abstrair complexidade e garantindo uma execução apropriada. A maior vantagem do padrão publish-subscribe encontra-se da natureza desacoplada de comunicação. - Neste estilo de comunicação é eliminada a necessidade de rastreamento de mensagens por parte do publisher ("Fire-and-forget"), possibilitando acrescentarmos novos assinantes ao fluxo sem risco de comprometer componentes existentes. - Estratégias de mensageria, storage e stream processing podem ser combinadas com microsserviços rodando em containers, juntamente com Apache Kafka podendo proporcionar uma base sólida de infra facilitando com que aplicações mais resilientes e orientada aos fluxos de eventos sejam entregues em ambiente distribuído de forma consistente e segura. - Arquiteturas event-streaming promovem o poder de notificações através de eventos, sendo utilizadas em diversas áreas como machine learning com análise de riscos, modelos de detecção de atividades suspeitas, processamentos em batch (lote), etc. Oferecendo informações mais úteis e beneficiando áreas de inteligência de negócio com processos que mantêm o estado de execução. Processos Stateful proporcionam possibilidade de armazenamento e agregação de dados de diversas fontes em uma determinada janela de execução, podendo ser utilizados em processos unbounded (sem início nem fim definidos). Se comparados a configuração e esforço necessários para adquirir os benefícios citados em grandes monólitos, evidentemente facilidades de plugar novas funcionalidades, desplugar componentes problemáticos tornam a adoção de estratégias event-streaming um caminho natural a ser seguido. Componentes Internos do Kafka Para suportar determinados requisitos complexos de aplicação, precisamos de uma tecnologia de mensagens durável, escalável, tolerante a falhas, confiável e altamente performática. Para isso, por oferecer baixa latência na entrega dos eventos, tecnologias como Apache Kafka poderiam ser adotadas como plataforma para processamento dos fluxos de eventos em tempo real. Diferente de Message Brokers tradicionais (RabbitMQ, ActiveMQ, etc), Kafka não foi desenhado para implementar protocolos como JMS, AMQP, etc. sendo desenhado para escalar. Para isso, Kafka executa através de um protocolo de mensagem binário sob TCP, podendo controlar centenas de operações de leitura e escrita por segundo de muitos produtores e consumidores em paralelo. ## Kafka utiliza um protocolo binário próprio, não implementando ou utilizando protocolos como AMQP (advanced message queuing protocol), STOMP (streaming text oriented messaging protocol), MQTT (message queuing telemetry transport) como utilizados no RabbitMQ. Kafka armazena streams de records em disco (file system), replicando para todos os brokers, promovendo fault-tolerance. Os dados são persistidos (duráveis) por um determinado período de tempo (de acordo com seu tamanho em bytes) e após isso são descartados por um processo de higienização do Kafka. Kafka essencialmente provê um durable message store (armazenamento durável), similar ao um log, o qual armazena streams de records em categorias chamadas tópicos, rodando em formato de cluster em um ou mais broker servers (node). Em teoria, podendo o cluster Kafka ser distribuído em múltiplos data centers. Kafka topics possuem partições as quais são endpoints para obtenção e armazenagem de records. Partições possuem segmentos onde cada record consiste de uma key (chave), value (payload persistido como byte array) e timestamp (data e hora). Kafka utiliza offsets nas partições para demarcar o índice de consumo de dados de um tópico, sendo controlados pelos consumers. Cada consumer deve pertencer a um consumer group (grupo de consumo), conceito utilizado pelo Kafka visando paralelizar o processamento entre uma coleção de consumers dentro de uma mesma partição. ## AMQP trata-se de um poderoso protocolo de comunicação com possibilidade de roteamentos avançados, mostrando como a mensagem deve ser transmitida, processada e consumida. **Partições no Kafka são utilizadas para paralelizar o processamento de eventos balanceando a carga entre os brokers do cluster (escalabilidade horizontal). Cada broker pode ter 0 ou N partições por tópico. Quando criamos um topic, informamos o número de partições que gostaríamos de usar, podendo ser somente acrescido posteriormente sendo o oposto não permitido. Estruturalmente, cada partição apresenta uma sequência ordenada, segmentada e imutável de records (Kafka change log), persistidos por um período de tempo relacionado a política de retenção. Nesse caso, sendo cada partição replicada entre os brokers, promovendo a tolerância a falhas, podendo se ter 2000 partições por broker, chegando a 200.000 por cluster.|** #### O papel principal de um broker resume-se a traduzir mensagens formais, de um remetente para um recipiente, assegurando a transmissão do ponto A para o ponto B por meio de roteamento. #### Cada record armazenado em uma partição possui seu offset definido quando o evento é persistido no broker. Desta forma, os consumers apontam para a última mensagem lida, escaneiam sequencialmente, lendo as mensagens em ordem enquanto salvam as últimas posições lidas no log com o auxílio do Zookeeper (armazena os metadados do cluster). Ocorre então a persistência dos metadados com informações sobre o processo e o estado atual do cluster.** #### Em versões novas do Kafka, brokers mantém informações sobre offset em um hidden topic (__consumer_offsets). No Kafka, brokers são nodes (nós) de um cluster, responsáveis por permitir ao Kafka receber mensagens de um producer, entregando-as ao consumer. Eventos são armazenados nas partições de um topic (fisicamente no disco), compondo o estado do cluster gerenciado pelo Zookeeper. #### Conceitualmente, dentro do contexto do Kafka, termos como Kafka Server, Kafka Broker, Kafka Node, etc. referem-se ao mesmo significado, sendo sinônimos. ### Partições nos tópicos são divididas em segmentos os quais são nomeados pela posição do último offset, possuindo um tamanho padrão de 1GB. Cada segmento é composto de um arquivo de log para armazenar a mensagem atual além de um arquivo de índice o qual armazena a posição da uma mensagem no log. #### Segmentos são configurados pelo tamanho em bytes e pelo tempo em que o Kafka aguardará até criar um novo log segment file, podendo variar com base em configuração do cluster. Partições são diretórios onde cada segmento consiste de um index file, time index file e log file, de forma que somente um segmento permanece ativo durante o ciclo de vida do processo. #### O número de partições nos mostra quantas requisições podem ser atendidas em paralelo pelos consumidores do tópico. #### Consumers são aplicações que se inscrevem em tópicos de forma a consumir seus records. Após a publicação da mensagem, pelo producer, todos os inscritos recebem o evento ocorrido em formato broadcast, bastando que ao inscrever-se, os consumidores informem qual a estratégia de commit do offset de mensagens, podendo ser: lidas no mínimo uma vez, lidas mais de uma vez, lidas somente uma vez. #### N- o contexto de processamento de eventos, Kafka apresenta duas estratégias de entrega de mensagens: synchronous replication mode (modo síncrono de replicação) e assynchronous replication mode (modo assíncrono de replicação). Ao utilizarmos a primeira estratégia, as mensagens somente estarão disponíveis para consumo quando todas as réplicas da partição confirmarem o recebimento dos dados através do commit. Quando o modo assíncrono é utilizado, o Kafka torna o record visível tão logo a mensagem é persistida na partição líder. ## Kafka e o Zookeeper **Zookeeper trata-se de um serviço de key/value (chave e valor) hierárquico para centralização de informações e sincronização de aplicações distribuídas. Provendo principalmente serviços de configuração, onde o Kafka utiliza o serviço oferecido pelo Zookeeper para armazenar informações de metadados do cluster, mantendo estes dados atualizados para brokers, tópicos, partições e réplicas.** - Kafka confia no Zookeeper para manter a coordenação e comunicação sobre a execução nos brokers (brokers são stateless) e também para notificar producers e consumers da existência de novos componentes adicionados ao Cluster, pois componentes podem ser adicionados em tempo real, como brokers, tópicos, partições, etc. - Zookeeper mantém informações sobre as partições líder presentes no cluster, armazenando o último offset de cada consumidor, possibilitando a recuperação de sua posição em caso de falhas. ### Além disso, Zookeeper mantém o controle de acesso aos topics e partitions utilizados pelo Kafka. Sendo responsável por determinar partições líder (leader partition) em tempo real. Partições líderes são encarregadas de controlar todas as leituras e escritas nas partições. Em contrapartida, partições réplicas (follower replicas) somente replicam o estado da partição líder distribuídas ao longo do cluster. - Réplicas seguidoras são elegíveis a se tornarem líderes quando encontram-se sincronizadas com o líder (in-sync), além de apresentarem bom histórico sem ocorrência de problemas em seu ciclo de vida. - Réplicas de partições são espalhadas por diversos brokers no cluster proporcionando alta disponibilidade de acesso. No Kafka, partições líderes gerenciam todas as leituras e escritas das partições réplica, realizando o tracking dos dados entre as operações de escrita. A principal vantagem do uso de partições no Kafka são: escalabilidade horizontal, aumento de performance, tolerância a falhas, e priorização no consumo dos eventos.