Quando você precisa reatribuir uma partição para outro broker ou brokers, a ferramenta kafka-reassign-partitions é muito útil. Ela é particularmente eficaz para reatribuir um pequeno número de tópicos. No entanto, observei algumas limitações após trabalhar na expansão de um cluster com mais de 5.000 tópicos.
Para realizar a reatribuição, é necessário executar três comandos distintos e criar dois arquivos JSON para cada reatribuição. Agora, imagine fazer isso para 5.000 tópicos! Embora seja possível construir um único arquivo JSON com uma lista de todos os tópicos e usar a opção `--throttle` para controlar a largura de banda, essa abordagem poderia potencialmente perturbar o ambiente. O que eu queria era reatribuir os tópicos um de cada vez e manter o controle sobre quais tópicos estavam sendo reatribuídos.
Foi precisamente o desafio que eu e meu colega Bruno Costa enfrentamos na semana passada. Nosso objetivo era reatribuir um tópico de cada vez, minimizando qualquer potencial impacto nos produtores e consumidores em execução, ao mesmo tempo que automatizávamos o processo. Como resultado, desenvolvemos um script Bash que simplifica a redistribuição das partições do Kafka. Este script pode ser utilizado para diversos fins, incluindo manutenção, escalonamento ou otimização de clusters.
#!/bin/bash
set +xoe pipefail
#################################################################
#
# This script uses Kafka's partition reassignment tool to move partitions across brokers.
# Kafka Docs reference:
# https://kafka.apache.org/26/documentation.html#basic_ops_cluster_expansion
#
# Usage:
#
# Create a text file (kafka-topics.txt) with the list of Kafka topics to reassign
# chmod +x ./kafka-reassign.sh
# ./kafka-reassign.sh
#################################################################
output_dir="./output"
[ -d $output_dir ] || mkdir $output_dir
banner()
{
echo "+------------------------------------------+"
printf "| %-40s |\n" "`date`"
printf "| %s \n" "${@//[$'\t\r\n']}"
echo "+------------------------------------------+"
}
input="kafka-topics.txt"
while IFS= read -r line
do
banner "Starting Topic ${line//[$'\t\r\n']}"
echo -e "\nReplacing topic in JSON template"
sed -e "s/<TOPIC>/${line//[$'\t\r\n']}/g" template.json > $output_dir/topics.json
echo -e "\nGenerating and cleaning reassign.json"
kafka-reassign-partitions --bootstrap-server ${BOOTSTRAP_SERVER} --topics-to-move-json-file $output_dir/topics.json --broker-list "0,1,2,3,4" --generate | awk '/Proposed partition reassignment configuration/{c=NR+2}(NR<=c){print}' | awk NR\>1 > $output_dir/reassign.json
echo -e "\nExecuting reassignment"
kafka-reassign-partitions --bootstrap-server ${BOOTSTRAP_SERVER} --reassignment-json-file $output_dir/reassign.json --execute
echo -e "\nVerifying reassignment"
kafka-reassign-partitions --bootstrap-server ${BOOTSTRAP_SERVER} --reassignment-json-file $output_dir/reassign.json --verify
count=$(kafka-reassign-partitions --bootstrap-server ${BOOTSTRAP_SERVER} --reassignment-json-file $output_dir/reassign.json --verify | grep -o "still in progress" | wc -l)
echo "partition reassignment in progress: $count"
while [ $count -gt 0 ]
do
sleep 5
count=$(kafka-reassign-partitions --bootstrap-server ${BOOTSTRAP_SERVER} --reassignment-json-file $output_dir/reassign.json --verify | grep -o "still in progress" | wc -l)
echo "partition reassignment in progress: $count"
done
done < "$input"
Você pode fazer o download do script aqui.
Aqui está uma descrição de cada parte do script e o que ela faz:
1. `set +xoe pipefail`: Essas são opções de shell. `+x` desliga a saída de depuração, `o` garante que o script saia se algum comando retornar um status não zero, e `e` assegura que, se parte de um pipeline falhar, o pipeline inteiro falhe.
2. O script inclui uma breve descrição de seu propósito e uso. Ele espera que um arquivo chamado `kafka-topics.txt` contenha uma lista de tópicos do Kafka a serem reatribuídos.
3. output_dir="./output": Isso define a variável `output_dir` como o diretório onde o script armazenará arquivos temporários e registros.
4. A função `banner()` imprime um banner carimbado com a hora no console para indicar quando uma nova reatribuição de tópicos está começando.
5. O script lê a lista de tópicos do Kafka do arquivo `kafka-topics.txt`, um por um, e executa as seguintes etapas para cada tópico:
- Cria um arquivo JSON chamado `topics.json` com base em um modelo `template.json`, substituindo `<TOPIC>` pelo nome real do tópico.
- Usa a ferramenta `kafka-reassign-partitions` para gerar um plano de reatribuição e armazena-o em `reassign.json`. Este plano especifica como as partições do Kafka devem ser movidas entre os brokers.
- Executa a reatribuição, movendo efetivamente as partições de acordo com o plano.
- Verifica o status da reatribuição e aguarda até que ela seja concluída.
O script repete essas etapas para cada tópico listado no `kafka-topics.txt`. Ele também continua verificando o status da reatribuição até que não esteja mais "em progresso" antes de passar para o próximo tópico.
Resultados
Usando este script, conseguimos reatribuir com sucesso 4.923 tópicos em apenas cerca de três dias, tudo isso sem causar qualquer interrupção para produtores e consumidores.
Conclusão
Isso marca a primeira versão do script, e continuaremos a aprimorá-lo conforme necessário. Para obter detalhes mais abrangentes sobre a ferramenta `kafka-reassign-partitions` e como ajustar seu uso para o seu cenário específico, recomendo consultar a documentação do Kafka. Isso permitirá fazer refinamentos e otimizações adicionais de acordo com suas necessidades.
Comments