Desvendando o KEDA: Construindo um Scaling eficiente com Apache Kafka

Rhian Lopes da Costa
Fretebras Tech
Published in
7 min readFeb 19, 2024

Já imaginou construir um scaling eficiente baseado no processamento de mensagens em Tópicos do Apache Kafka?! Nesse artigo vamos explorar o KEDA, uma extensão do Kubernetes que permite escalar automaticamente os workloads com base em eventos.

Pré-requisitos

Como requisito fundamental para este artigo, é imprescindível utilizar o Playground desenvolvido no artigo anterior, com ele configuraremos um scaling eficiente para o consumer.

Introdução

O ecossistema Kubernetes continua a evoluir, proporcionando soluções cada vez mais avançadas para gerenciar e escalar aplicativos de maneira eficiente. Entre essas inovações, destaca-se o Kubernetes Event Driven Autoscaler (KEDA), uma ferramenta que promete revolucionar a escalabilidade de aplicações baseadas em eventos. Exploraremos a ferramenta com ênfase em seu uso para scaling consumers de tópicos do Apache Kafka.

Em vez de operarem como consumers ativos 24 horas por dia, 7 dias por semana ou possuirem quantidade de réplicas fixas, esses consumers agora podem tornar-se reativos, escalando conforme a fila de novas mensagens disponíveis para processamento.

Instalação do KEDA

Conforme mencionado anteriormente, o KEDA é uma extensão do Kubernetes. Com o Playground configurado conforme instruções no artigo anterior, podemos agora proceder com a instalação do KEDA.

Este processo será realizado utilizando o Helm. Na documentação do KEDA, uma tabela lista as compatibilidades entre as versões da ferramenta e as versões do cluster Kubernetes.

https://keda.sh/docs/operate/cluster/#kubernetes-compatibility

A versão do Kubernetes instalada localmente no último artigo é a v1.26, por tanto iremos utilizar a versão v2.12 do KEDA.

Podemos verificar a versão do servidor local a partir do seguinte comando:

$ kubectl version
...
Server Version: v1.26.4+k3s1

Com a versão do KEDA especificada, podemos realizar a instalação executando os comandos abaixo:

helm repo add kedacore https://kedacore.github.io/charts

helm repo update

helm install keda kedacore/keda --version 2.12 --namespace keda --create-namespace

Novo template Helm

Com o KEDA instalado, iremos agora atualizar o template Helm do nosso consumer que hoje possui apenas um manifesto de Deployment. Para isso, iremos nos basear na documentação do KEDA com o scaler escolhido, em nosso caso o Apache Kafka.

Além da documentação, continuaremos utilizando o consumer construído em nosso último artigo mas agora utilizaremos um novo template Helm. Caso não tenha realizado anteriormente, é necessário clonar o seguinte repositório:

Com o repositório em mãos, utilizaremos o seguinte template helm "consumer-keda".

helm-charts/
consumer/ <-- Template antigo
...
consumer-keda/ <-- Novo template
templates/
deployment.yaml
scaler.yaml
Chart.yaml
values.yaml

Nesse novo template temos um arquivo chamado "scaler.yaml", nesse arquivo temos o seguinte manifesto seguindo a documentação do KEDA com o scaler Kafka:

Além disso, temos novos campos no arquivo "values.yaml", adicionados os campos necessários para configurarmos o scaler do Kafka.

Lembre-se de preencher o "<client_password>" que pode ser obtido a partir do seguinte comando visto no artigo anterior:

kubectl get secret kafka-user-passwords --namespace kafka -o jsonpath='{.data.client-passwords}' | base64 -d | cut -d , -f 1

Cada um dos campos tem sua função e valores padrões, além de diversos outros que podem ser configurados, segue abaixo os links da documentação do KEDA e do scaler Apache Kafka com mais detalhes sobre cada um dos campos e todos disponíveis.

https://keda.sh/docs/concepts/scaling-deployments/
https://keda.sh/docs/scalers/apache-kafka/

A customização dos valores de pollingInterval, cooldownPeriod e lagThreshold é de suma importância para o sucesso do seu consumer em um ambiente produtivo, para exemplificação os valores ficaram reduzidos a fim de facilitar os testes, em um cenário produtivo devem ser re-avaliados esses valores para cada caso.

Deploy

Com o novo template Helm, podemos realizar o deploy do nosso consumer a fim de validar seu funcionamento, para isso, execute o comando abaixo na raiz do repositório de playground para atualizarmos o template do consumer:

helm upgrade --install kafka-consumer helm-charts/consumer-keda -f helm-charts/consumer-keda/values.yaml --namespace dev-kafka-consumer --create-namespace

Com isso, podemos executar o seguinte comando para acompanhar as verificações do KEDA e validar seu funcionamento:

$ kubectl describe scaledobject -n dev-kafka-consumer
...
Hpa Name: keda-hpa-kafka-consumer
Original Replica Count: 1
Scale Target GVKR:
Group: apps
Kind: Deployment
Resource: deployments
Version: v1
Scale Target Kind: apps/v1.Deployment
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal KEDAScalersStarted 30s keda-operator Scaler kafka is built.
Normal KEDAScalersStarted 30s keda-operator Started scalers watch
Normal ScaledObjectReady 30s keda-operator ScaledObject is ready for scaling
Normal KEDAScaleTargetDeactivated 30s keda-operator Deactivated apps/v1.Deployment dev-kafka-consumer/kafka-consumer from 1 to 0

Observamos que o KEDA fez o downscaling para o mínimo de réplicas assim que foi instalado, pois não possui mensagens disponíveis para processamento.

Podemos também verificar via painel do Rancher que nosso Deployment do consumer está zerado.

Para validarmos o funcionamento do scaler, basta produzirmos uma nova mensagem no tópico do kafka.

Atualmente o "pollingInterval" do nosso scaler do KEDA é de 10 segundos, após esse intervalo o consumer será ativado a fim de processar a nova mensagem disponível no tópico do Kafka.

Com a mensagem processada, o nosso "cooldownPeriod" é de 30 segundos, após esse intervalo iniciará o processo de downscaling do consumer.

Com isso, temos nosso consumer com scaling baseado em eventos externos do Apache Kafka! 🚀

Scaling

Se pensarmos em um cenário de arquitetura orientada a eventos com milhares de processamento por hora, é importante realizarmos o scaling de réplicas do nosso Deployment baseado nas mensagens pendentes de processamento a fim de aumentarmos a eficiência do scaling.

Com esse cenário em mãos podemos continuar utilizando o KEDA apenas revisando os valores dos campos "maxReplicas", "pollingInterval", "cooldownPeriod" e "lagThreshold".

Devemos aumentar o número máximo de réplicas a fim de observarmos o scaling de réplicas, também devemos aumentar o valor de “pollingInterval”, pois pensando em um cenário de alto processamento deixa de fazer sentido um curto intervalo de verificação para scaling, além de precisarmos desse intervalo para adicionarmos as mensagens no tópico.

Como estamos apenas o log do conteúdo da mensagem processada, não iremos atualizar o campo "cooldownPeriod", pois o valor dele deve ser no mínimo o tempo máximo de processamento de uma mensagem.

E por fim o campo "lagThreshold" manteremos um valor baixo a fim de observarmos o scaling de réplicas acrescentando poucas mensagens no tópico.

Com isso, atualizamos os seguintes valores do "values.yaml":

E podemos realizar um novo deploy a partir do template executando o seguinte comando helm novamente:

helm upgrade --install kafka-consumer helm-charts/consumer-keda -f helm-charts/consumer-keda/values.yaml --namespace dev-kafka-consumer --create-namespace

Com isso, aproveitamos os 120 segundos de "pollingInterval" para produzir um total de 8 mensagens na fila.

Após aguardarmos o tempo restante do intervalo entre as verificações, é possível observar o funcionamento das configurações de scaling ao limite de réplicas.

É importante ressaltar a importância do acompanhamento e refino dos valores no ambiente produtivo a fim de configurar com eficiência o scaling

Conclusão

O KEDA é uma ferramenta poderosa que deve ter seu uso disseminado, pois tem muito potencial para um scaling eficiente de réplicas, principalmente em cenários de arquitetura orientada a eventos onde muitas as vezes não conseguimos metrificar a alta demanda de processamento apenas por métricas simples como CPU ou Memória, realizando o scaling baseado nas mensagens pendentes de processamento no tópico.

Além disso, o KEDA possui uma infinidade de scalers externos que possui compatibilidade como MySQL, MongoDB, AWS SQS, etc… Podendo ser utilizado em diversos cenários e abstraindo muitas lógicas como Cronjobs ou Jobs criados para execução a partir de uma alteração de status em um banco de dados por exemplo.

São diversos os cenários onde o KEDA pode contribuir e construirmos scalers robustos e eficientes para atender o dia a dia de milhares de serviços e aplicações.

Meu objetivo principal com esse artigo é exemplificar o uso do KEDA com um cenário de scaling baseado no Apache Kafka, mas aproveito para disseminar o potencial da ferramenta em diversos cenários.

Qualquer dúvida podem me chamar!

Obrigado pela sua atenção! E até breve 😄

--

--

Rhian Lopes da Costa
Fretebras Tech

Olá! Me chamo Rhian, sou apaixonado por resolver problemas utilizando Tecnologia e Inovações