Apache Kafka, isso é pra mim ?
Com os sistemas computacionais cada vez maiores e tendo que suportar um tráfego crescente, uma das áreas que mais cresceu foi a arquitetura distribuída.
Os microservices ocupam um lugar de destaque sugerindo serviços cada vez menores e com funções muito bem definidas. No entanto, a necessidade de fazer esses serviços se comunicarem de forma eficiente cresceu em uma escala ainda maior.
Uma das abordagens mais comuns é a utilização de uma fila entre os serviços de forma que o serviço A publica algo em uma fila e o serviço B consome essa fila, sem que os serviços sequer precisem se conhecer. A vantagem dessa abordagem é levar a independência entre eles muito a sério, de forma que, se o serviço A requisita algo ao serviço B e este por exemplo estiver fora do ar isso não é perceptível ao serviço A. Nesse caso, os pacotes ficarão nesta fila e, assim que o serviço B voltar, ele apenas consumirá toda a fila.
Existem vários provedores de serviço para essa arquitetura, por exemplo, RabbitMQ, AWS SQS, Google Cloud PubSub e o Apache Kafka. Pra quem busca uma solução totalmente gerenciada, o PubSub e SQS sempre foram as melhores opções, tendo o primeiro demonstrado nos meus testes um desempenho bastante superior. No entanto com o recente anúncio da disponibilidade do Apache Kafka no Google Cloud e AWS ele passou a ser uma excelente opção.
Apache Kafka
Formalmente o Apache Kafka se define como uma plataforma distribuída de streaming. Vamos destrinchar o conceito …
Uma plataforma de streaming tem três características:
- Publicar e assinar um stream de registros, similar a uma fila de mensagens.
- Gravar streams de registros de uma forma durável e tolerante a falhas.
- Processar streams de registros à medida que eles ocorrem.
Aqui o Kafka empata em algum sentido com o PubSub com a exceção de que as mensagens ficam no PubSub apenas por 7 dias.
Kafka é geralmente usado para duas classes de aplicações:
- Construir pipelines de dados em streaming que trocam dados de forma confiável entre as aplicações.
- Construir aplicações de streaming que transformam ou reagem à streams de dados.
Esse são os conceitos mais importantes do Kafka:
- Roda em um cluster em um ou mais servidores que podem se distribuir em múltiplos data centers.
- Tais clusters armazenam streams de registros em categorias chamadas de tópicos.
- Cada registro consiste de uma chave, um valor e um timestamp.
Tópicos
Um tópico é uma categoria ou nome do feed aos quais um registro é publicado. Eles são multi-subscriber de forma que um tópico pode ter zero, um ou muitos consumers que assinam o tópico para receber os registros publicados nele.
Tais registros permanecem ordenados, imutáveis e novos registros são continuamente adicionados. Cada registro é associado uma um id sequencial chamado de offset que unicamente identifica cada registro em uma partição.
Esses dados serão mantidos de acordo com a configuração escolhida. Por exemplo, ao se escolher 10 dias de retenção, então por 10 dias a partir de quando foi publicado, ele estará disponível para qualquer consumidor.
A performance é efetivamente constante em relação ao tamanho dos dados armazenados de forma que armazenar dados por muito tempo não será um problema.
De fato,o único metadado mantido para cada consumer é a posição de offset em que ele se encontra. O offset é controlado pelo consumer, de forma que ele pode seguir o caminho e consumir cada registro de forma sequencial ou mesmo retornar para um offset mais antigo para reprocessar os dados.
Essa é a característica que torna o Kafka um dos melhores candidatos para aqueles que optem por um event sourcing.
Event sourcing
Basicamente no event sourcing armazena-se todos os eventos e, ao solicitar o estado da aplicação, reprocessa-se os eventos e constroe-se o estado. No caso de uma conta bancária por exemplo, não se armazenaria o saldo. A cada solicitação do saldo os eventos(créditos e débitos) são reprocessados. Dentre as vantagens estão a possibilidade de saber estados anteriores da aplicação(um linha do tempo de estados), um registro detalhado de todos os eventos e a possibilidade de reprocessar os eventos sempre que necessário.
Gerenciado ou não
Ter um cluster de Kafka parece uma solução tentadora para quem pensa em arquitetura distribuída utilizando filas. No entanto, o peso e a responsabilidade de manter tudo isso é algo que assusta principalmente em tempos de cloud.
No entanto a confluent (empresa fundada pelos criadores do Kafka) oferece uma versão fully managed no Google Cloud ou AWS. Nesse caso, tem-se todo o poder do Kafka sem se preocupar com a complexa administração do cluster. Atualmente o custo para Google cloud na versão professional fica em $0,55/hora.
Embora o Pub Sub não ofereça tantos recursos quanto o Kafka, falando-se em versões totalmente gerenciadas, o preço (e modelo de cobrança) é muito mais agradável: $19 para cada 10 milhões de mensagens.
Contra-exemplo
Embora a migração do Google Pub Sub para o Kafka pareça uma evolução, existe o gigantesco exemplo o spotify que fez exatamente o contrário no seu famoso artigo da migração para o google cloud.
Veredito
Existem boas soluções de filas como RabbitMQ, Pub Sub, e Kafka.
O RabbitMQ é sem dúvida aquele com mais recursos para se lidar especificamente com filas mas não há uma versão totalmente gerenciada para o google cloud. Isso pode ser um entrave para aqueles que não querem a responsabilidade de administrar o cluster.
O Google PubSub é a opção mais simples e mais barata de um serviço de filas totalmente gerenciado tendo como desvantagens a não garantia de ordem das mensagens e a eventual duplicação de eventos mas em muitos cenários pode ser um excelente ponto de partida ou mesmo a solução perfeita.
O Kafka seria um message queue com esteroides que oferece muitos recursos adicionais. A forma de armazenamento permitindo reprocessar eventos antigos é um grande diferencial. A recente versão para cloud remove um entrave gigantesco que é a complexa administração do cluster mas seu uso ainda esbarra no elevado custo.