Atualmente o Kafka é utilizado para realizar transferência de dados entre aplicações.
4 | Como podemos notar, o volume de dados está crescendo a cada dia e, além disso, não podemos correr o
5 | risco de perder dado por algum bug da aplicação, deploy, entre outros.
6 |
Imagine a compra de um livro na amazon:
7 |
8 | * O pagamento é realizado pelo cartão de crédito;
9 | * A operadora precisa se certificar que tenha limite no cartão;
10 | * Se os dados estão corretos;
11 | * Se não é fraude;
12 | * E Mais algumas validações.
13 |
14 |
Nesse exemplo podemos ter várias aplicações (micro-services) com as suas regras de negócio isoladas,
15 | recebendo estímulos para processar essas informações e não precisam se preocupar
16 | com entrega/captura dos dados para processamento.
17 |
E a partir dai adentramos no data streaming.
18 |
19 |
20 |
21 | *Exemplo de comunicação de sistema.*
22 |
23 | ## Data Streaming
24 |
25 |
Data streaming é um fluxo constante e sem controle de dados, normalmente não se sabe onde
26 | começa e termina o fluxo. Os dados vão sendo processados a medida que chegam no seu consumidor,
27 | praticamente em tempo real.Mas não quer dizer que essa é apenas a sua única caraterística,
28 | os dados também podem ser processados em batch ou lote com hora e data pré-estabelecidas.
29 |
Os dados chegam através de mensagens que são armazenadas, permitindo paralelizar
30 | o processamento entre aplicações ou apenas processar de forma assíncrona.
31 |
Pode-se usar esse forma de processamento em qualquer ramo para agilizar:
32 |
33 | * Bancário;
34 | * Imobiliário;
35 | * Industrial;
36 | * E até mesmo para migração de grandes bases de dados.
37 |
38 |
39 | ## Mas afinal, o que é Kafka?
40 |
41 |
42 |
43 |
O Apache Kafka foi um sistema desenvolvido pelo Linkedin para streaming de dados. E atualmente Netflix,
44 | Spotify, Uber, Twitter e o próprio Linkedin estão utilizando nas suas plataformas para auxiliar no processamento de informaçöes.
45 |
Originalmente foi criado para ser um sistema baseado em logs e teve até os seguintes nomes:
46 | write-ahead logs, commit logs ou até mesmo transaction logs.
47 |
Para auxiliar no entendimento dessa prática, explicitamos abaixo o funcionamento das técnicas:
48 |
49 | * Write-ahead Logs (WAL), commit logs ou transaction logs se baseiam numa técnica
50 | que fornece atomicidade e durabilidade (propriedades do ACID -
51 | Atomicidade, Consistência, Isolamento e Durabilidade) num sistema de banco de dados.
52 | A técnica consiste em gravar todas as informações em logs e depois aplica-los no banco de
53 | dados. Exemplo de um cenário que essa técnica pode ser extremamente útil:
54 | * Se a máquina onde a aplicação de um banco está perde energia ou é desligada no meio de um processo.
55 | Ao religa-la, essa aplicação precisará de informação do processo que estava realizando,
56 | se foi concluído com sucesso ou continuar de onde parou.
57 | A aplicação do banco que utliza essa técnica, consultará os logs pra obter essas informações.
58 |
59 | *Lembrando que um log é nada menos que uma forma de armazenamento de dado,
60 | onde toda nova informação é adicionada no final do arquivo. Esse é o princípio do Kafka.*
61 |
62 | ## Kafka e suas funcionalidades
63 |
64 | * Publish/Subscribe — é um pattern que consiste em ter um ou mais publicadores que terá um ou mais
65 | consumidor/inscrito e as duas pontas trocam mensagens de forma indireta.
66 | Dentro desse pattern temos uma subdivisão de publicador/canal, evento/publicação e inscrito/assinante.
67 |
68 |
69 | * Sistema de armazenamento, por padrão as mensagens são armazenadas por 7 dias, mas pode ser alterado
70 | para armazenar indefinidamente.
71 |
72 |
73 | * Processamento de stream: processamento imediato de um fluxo de mensagens (data streaming).
74 |
75 | \
76 | *Pattern publish/subscribe*
77 |
78 |
79 | O Kafka é um intermediário que trabalha coletando informações e armazenando para os consumidores.
80 |
81 |
82 |
83 | O kafka vem sendo adotado para processos ETL(Extract Transform and Load), de forma a copiar os dados
84 | de uma banco de dados tradicional (OLTP) para um analítico (OLAP).
85 | * ETL: é um data integration em 3 etapas, que consiste em extração, transformação e carregamento de dados.
86 | Utilizado normalmente para combinar dados de diversas fontes gerando um data warehouse. Para alguns, o futuro
87 | do ETL seja utilizar kafka para diminuir a dificuldade desse processo.
88 |
89 | # Nomenclatura, conceitos e características
90 |
91 |
92 | A mensagem ou evento é composto por:
93 | - Nome do Tópico: fila ao qual mensagem será postada/gravada;
94 | - Partição: subdivisão de um tópico, a partição ajuda no balanceamento de carga, entre outras funções.
95 | - Timestamp: data e hora dos registros para ordenação fifo.
96 | - Chave: utilizada para cenários mais avançados, não abordaremos esses cenários por enquanto;
97 | - Valor: informação que deseja se enviar, normalmente composta por json, xml ou até mesmo uma string.
98 |
99 | No kafka, temos as seguintes arquiteturas de mensageiria:
100 | * Publish-subscribe;
101 | * Point-to-point.
102 |
103 | O modelo point-to-point é baseado em conceito de filas, onde o produtor envia a mensagem para
104 | uma fila especifica, que a armazena para entregar ao consumidor ou até a mensagem expirar
105 | (Dependendo da configuração de armazenamento da mensagem, a mesma pode ficar eternamente na fila).
106 | Caso essa fila possua mais de um consumidor apenas um a receberá.
107 |
108 |
109 |
110 | O modelo do publish/subscribe se baseia na troca de mensagens utilizando o modelo de tópicos, onde as mensagens
111 | são enviadas para os consumidores que assinaram o tópico.
112 | Ao contrário do point-to-point esse modelo permite que envie a mesma mensagem para vários
113 | consumidores.
114 |
115 |
116 |
117 |
118 |
O Apache Kafka trabalha com o publish/subscribe, pois a solução tem baixa latência
119 | para receber e enviar as mensagens.
120 | Além do pattern, a arquitetura ainda possui as seguintes características:
121 |
122 | - Escalabilidade: o cluster do Kafka permite o redimensionamento para atender a demanda de maneira simples;
123 | - Distribuído: o cluster pode operar com vários nós (brokers) para facilitar o processamento;
124 | - Replicado, particionado e ordenado: as mensagens podem ser replicados na ordem que chegam para
125 | facilitar processamento, segurança e auxiliar na velocidade de entrega.
126 | - Alta disponibilidade: o cluster tem diversos nós (brokers) e várias cópias tornando-o
127 | sempre disponível caso um nó esteja indisponível.
128 |
129 |
130 | # Arquitetura Apache Kafka
131 |
132 |
Arquitetura do Kafka é composta por producers, consumers e o seu cluster.
133 |
134 |
135 |
136 |
O producer é qualquer aplicação que publica uma mensagem no Kafka. O consumer é qualquer aplicação que
137 | consume as mensagens do kafka. Já o cluster é conjunto de nós (brokers kafka) que funcionam
138 | como única instância de serviço da mensageria.
139 |
140 |
Um cluster Kafka possui vários brokers. Um broker ou nó é um servidor kafka que recebe as mensagens dos produtores
141 | e as armazena em disco com uma chave exclusiva de offset.
142 |
Um broker do Kafka permite que os consumidores busquem a mensagem por tópico, group id, partição e offset.
143 | Brokers fazem parte de um cluster compartilhando informações entre si direta ou indiretamente,
144 | sendo que um dos brokers atua como controlador(controller).
145 |
146 |
Para gerenciar os brokers do Kafka temos o Zookeeper que armazena todos os metadados dos cluster,
147 | partições, nomes tópicos e os nós disponíveis, além de manter a sincronização entre os clusters.
148 |
Em caso de queda de algum cluster o Zookeeper elege o próximo cluster que irá substituir.
149 |
150 |
151 |
152 | #### Acesso Sequencial ao Disco
153 | *O Kafka trabalha com gravação e leitura sequencial no disco para garantir que não há perda de dados,
154 | caso aconteça algum desligamento acidental da máquina. Esse acesso permite que o Kafka saiba onde
155 | começa e onde termina cada bloco de mensagens.*
156 |
157 |
158 | # Ferramentas semelhantes
159 |
160 |
Existe outras ferramentas similares ao Kafka, como :
Sendo que cada uma possui as suas características especificas.
166 |
167 |
168 | # Hands on
169 |
Agora que já apresentamos os principais conceitos do Kafka, vamos por a mão na massa.
170 |
Começando pelo nosso docker compose que será responsável por subir o nosso cluster.
171 |
172 |
Utilizamos as imagens do confluentinc por serem mais estáveis e confiáveis, abaixo apresentamos a configuração básica do zookeeper:
173 |
174 | zookeeper:
175 | image: confluentinc/cp-zookeeper:5.1.2
176 | restart: always
177 | environment:
178 | ZOOKEEPER_SERVER_ID: 1
179 | ZOOKEEPER_CLIENT_PORT: "2181"
180 | ZOOKEEPER_TICK_TIME: "2000"
181 | ports:
182 | - "2181:2181"
183 |
184 | * ZOOKEEPER_SERVER_ID: necessário apenas para executar no modo de cluster,
185 | definindo o ID do servidor. Por exemplo, o id do servidor 1 conteria apenas o texto “1“.
186 | O ID deve ser exclusivo dentro do conjunto e deve ter um valor entre 1 e 255.
187 | * ZOOKEEPER_CLIENT_PORT : informa a porta que os clientes do Kafka irão escutar.
188 | * ZOOKEEPER_TICK_TIME : unidade de tempo utilizada pelo zookeeper para validações.
189 |
190 | kafka1:
191 | image: confluentinc/cp-kafka:5.1.2
192 | depends_on:
193 | - zookeeper
194 | ports:
195 | - "29092:29092"
196 | environment:
197 | KAFKA_ZOOKEEPER_CONNECT: "zookeeper:2181"
198 | KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
199 | KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
200 | KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka1:9092,PLAINTEXT_HOST://localhost:29092
201 | KAFKA_BROKER_ID: 1
202 | KAFKA_BROKER_RACK: "r1"
203 | KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
204 | KAFKA_DELETE_TOPIC_ENABLE: "true"
205 | KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
206 |
207 | * KAFKA_ZOOKEEPER_CONNECT: porta ao qual o Kafka irá se conectar ao zookeeper;
208 | * KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: define chave/valor para o protocolo de segurança a ser usado,
209 | por nome de listerner;
210 | * KAFKA_INTER_BROKER_LISTENER_NAME: define qual listener usar para comunicação entre brokers.
211 | Os brokers comunicam-se entre si, geralmente usando uma rede interna(rede docker como o nosso case).
212 | * KAFKA_ADVERTISED_LISTENERS : lista de listeners com host/ip. São esses os metadados que serão
213 | devolvidos para clientes.
214 | * KAFKA_BROKER_ID: identificação do broker kafka.
215 | * KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: essa configuração define o fator de replicação
216 | do tópico para segurança, caso o broker caia e tenha outro de backup, o consumidor seria direcionado
217 | para o backup não havendo perda de mensagens. Nosso caso setamos o valor como 1 por ter somente um broker.
218 | * KAFKA_DELETE_TOPIC_ENABLE: habilita a remoção de tópicos;
219 | * KAFKA_AUTO_CREATE_TOPICS_ENABLE: habilita a criação automatica de tópicos;
220 |
221 |
Para simularmos um ambiente de micro-services de compras geramos vários módulos dentro do projeto,
222 | sendo que common-kafka se tornou compartilhado entre todos para reutilização do código.
223 |
O service-new-order responsável por postar (producer) as mensagens nas filas e os
224 | service-fraud-detect-service, service-email e service-log são responsáveis pela leitura das mensagens
225 | (consumers).
226 |
227 |
Dentro do commons temos a classe KafkaDispatcher que é nossa classe responsável por conectar no Kafka e
228 | enviar as mensagens para fila. Abaixo as propriedades que utilizamos para conectar no kafka:
229 |
230 | private static Properties properties() {
231 | var properties = new Properties();
232 | properties.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "127.0.0.1:29092");
233 | properties.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
234 | properties.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, GsonSerializer.class.getName());
235 | return properties;
236 | }
237 |
238 |
239 | * ProducerConfig.BOOTSTRAP_SERVERS_CONFIG: configuração para conexão da nossa aplicação java no Kafka. A porta
240 | normalmente é 9092 caso instale diretamente na sua máquina local sem usar containers. Poderíamos
241 | mudar o nosso parâmetro de ports que esta sendo externalizadas no docker-compose, mas resolvemos deixar
242 | como na documentação.
243 | * ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG: classe responsável por serializar nossa chave
244 | que está sendo enviada com o objeto da mensagem.
245 | * ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG: classe responsável por serializar o nosso objeto
246 | que está sendo enviado.
247 |
248 |
No método abaixo send, enviamos o tópico ao qual queremos postar a mensagem, caso o tópico não exista
249 | já é criado de forma automática. Como o método send do producer precisa de uma chamada de callback para
250 | o caso de falha, criamos um básico apenas para enviá-lo como parâmetro e imprimir a excessão para
251 | investigarmos a causa de alguma possível exceção.
Criamos uma abstração para reaproveitar o código nos consumers, onde instanciamos o KafkaService
267 | enviando os parâmetros necessários para consumo da fila.