Изучаем Apache Kafka с нуля. Урок 11. kafka-cluster.sh

Изучаем Apache Kafka с нуля. Урок 11. kafka-cluster.sh

В уроке 10 мы разобрали kafka-storage.sh — утилиту, которая работает с хранилищем метаданных напрямую через файловую систему. Она генерирует cluster ID, форматирует директорию и записывает meta.properties. Но всё это происходит в оффлайне — до старта брокера.

Теперь представьте обратную ситуацию: кластер уже запущен и работает, и вам нужно узнать его cluster ID по сети. Или вы навсегда выводите из строя один из брокеров и хотите, чтобы KRaft убрал его запись из метаданных. Для этих задач существует kafka-cluster.sh.

Утилита небольшая — всего две подкоманды. Но каждая закрывает конкретный сценарий администрирования. Глубже эти сценарии разбираются в курсе «Администрирование кластера Kafka», включая практику на реальных многонодовых конфигурациях.

 

Что такое kafka-cluster.sh

kafka-cluster.sh — утилита для получения информации о запущенном кластере и управления регистрацией брокеров в KRaft-метаданных. В отличие от kafka-storage.sh, она работает только с живым кластером — через сетевое соединение с брокером по флагу —bootstrap-server.

У утилиты две подкоманды:

  • cluster-id. Запрашивает у работающего брокера уникальный идентификатор кластера и выводит его в stdout. Полезна для сверки с тем, что записано в meta.properties, и для диагностики расхождений между нодами.
  • unregister. Удаляет запись о брокере из KRaft-метаданных. Используется при постоянном выводе брокера из кластера, когда нужно убрать его из списка участников.

Обе подкоманды специфичны для KRaft-режима. В старых кластерах на ZooKeeper аналогичные задачи решались через ZooKeeper CLI — прямой работой с znode-записями.

 

Подкоманда cluster-id. Получение идентификатора кластера

Подкоманда cluster-id делает ровно одно: подключается к брокеру и возвращает UUID кластера. Это тот же идентификатор, который был сгенерирован командой kafka-storage.sh random-uuid при инициализации и записан в meta.properties.

kafka-cluster.sh cluster-id --bootstrap-server localhost:9092

Вывод будет коротким:

Cluster ID: xtzWnoMyEkahzrAFKnMzmg

Строку с идентификатором удобно сохранить в переменную — например, для сравнения с содержимым файла meta.properties:

# Получить cluster ID от живого брокера
CLUSTER_ID_LIVE=$(kafka-cluster.sh cluster-id \
  --bootstrap-server localhost:9092 | awk '{print $3}')

# Прочитать cluster ID из meta.properties
CLUSTER_ID_FILE=$(grep cluster.id \
  /tmp/kraft-combined-logs/meta.properties | cut -d= -f2)

# Сравнить
if [ "$CLUSTER_ID_LIVE" = "$CLUSTER_ID_FILE" ]; then
  echo "OK: cluster ID совпадает"
else
  echo "MISMATCH: $CLUSTER_ID_LIVE vs $CLUSTER_ID_FILE"
fi

Такая проверка полезна в автоматизированных скриптах развёртывания: если идентификаторы расходятся, значит брокер был переинициализирован с другим UUID и отказался бы присоединиться к кластеру.

 

Когда cluster ID может не совпасть

В штатной ситуации cluster ID одинаков на всех нодах и не меняется. Расхождение — признак нештатной ситуации. Вот типичные причины.

  • Повторное форматирование без —ignore-formatted. Если на одной из нод запустить kafka-storage.sh format с новым UUID, эта нода получит другой идентификатор. Брокер завершится с ошибкой несоответствия кластера при попытке подключиться.
  • Восстановление из резервной копии meta.properties. Если файл был скопирован с другого кластера, UUID в нём будет чужой.
  • Тестовая среда после пересоздания. Если тестовый кластер пересоздавали, а конфигурация скриптов подтягивает старые переменные, можно получить рассинхронизацию.

Подкоманда cluster-id даёт быстрый ответ: «что видит живой брокер» — без необходимости лезть в файлы или перезапускать службу.

 

Подкоманда unregister. Вывод брокера из кластера

В KRaft-режиме каждый брокер регистрируется в логе метаданных __cluster_metadata при первом запуске. Эта запись хранится в метаданных даже после того, как брокер остановлен. Пока запись есть, контроллер считает брокер участником кластера — просто временно недоступным.

Если брокер остановлен навсегда (железо вышло из строя, нода исключается из инфраструктуры), его запись нужно явно удалить. Иначе контроллер будет ждать его возврата и сигнализировать о нехватке реплик. Именно для этого существует unregister.

# Брокер с ID=2 должен быть остановлен перед разрегистрацией
kafka-cluster.sh unregister \
  --id 2 \
  --bootstrap-server localhost:9092

При успехе утилита выведет подтверждение:

Broker 2 is no longer registered.

Если попытаться разрегистрировать работающий брокер, команда вернёт ошибку. KRaft не позволяет удалить из метаданных брокер, у которого активны реплики партиций.

Перед выполнением unregister убедитесь, что выполнены несколько условий.

  • Брокер остановлен. Сначала выполните kafka-server-stop.sh, дождитесь завершения процесса.
  • Данные перераспределены. Если на брокере были партиции, перед остановкой их нужно переназначить на другие ноды через kafka-reassign-partitions.sh (урок 22).
  • Фактор репликации позволяет. Нельзя вывести брокер, если это нарушит минимальный ISR для активных топиков.

Разрегистрация — необратимое действие для этого экземпляра брокера. Если брокер с тем же ID позже запустится снова на той же ноде, он зарегистрируется заново как новый участник.

 

Сравнение подходов к получению cluster ID

Для одной и той же задачи — узнать UUID кластера — существует несколько способов. Они отличаются по условиям применения.

Метод Брокер должен быть запущен Что читает Подходит для автоматизации
kafka-cluster.sh cluster-id да живой брокер по сети да
kafka-storage.sh info нет meta.properties на диске да
grep cluster.id meta.properties нет meta.properties напрямую да, но хрупко
Kafka Admin API (describeCluster) да брокер по сети да, в Java/Python-коде

В production-окружении рекомендуется использовать kafka-cluster.sh cluster-id для онлайн-проверок и kafka-storage.sh info для оффлайн-диагностики. Прямое чтение meta.properties через grep — вспомогательный вариант, зависящий от структуры файла.

 

Рабочий сценарий. Плановый вывод брокера

Ниже — полная последовательность действий при плановом выводе брокера из трёхнодового кластера. Каждый шаг выполняется на управляющей машине или на самом брокере.


# 1. Убедиться, что кластер здоров и знает текущий cluster ID
kafka-cluster.sh cluster-id --bootstrap-server localhost:9092

# 2. Перед остановкой - убедиться, что партиции с этого брокера переехали
#    (подробнее в уроке 22 про kafka-reassign-partitions.sh)

# 3. Остановить брокер (например, с ID=2) на целевой ноде
kafka-server-stop.sh

# 4. Разрегистрировать брокер из метаданных кластера
kafka-cluster.sh unregister \
  --id 2 \
  --bootstrap-server localhost:9092

# 5. Убедиться, что оставшиеся брокеры в норме
kafka-metadata-quorum.sh describe --status \
  --bootstrap-server localhost:9092

Шаг с kafka-metadata-quorum.sh разберём подробнее в следующем уроке. Пока важно понять цепочку: сначала данные, потом остановка, потом разрегистрация — в строго таком порядке.

 

Схема проверки и вывода брокера

Для наглядности — полная последовательность от диагностики cluster ID до удаления брокера из метаданных KRaft.

Схема вывода брокера Apache Kafka из рабочего кластера - уроки Школы Больших Данных


 

 

Что дальше

Теперь у вас есть два инструмента для работы с идентификацией кластера: kafka-storage.sh для оффлайн-инициализации и kafka-cluster.sh для онлайн-диагностики и управления составом участников.

В уроке 12 разберём kafka-metadata-quorum.sh. Это главный инструмент для диагностики состояния KRaft-кворума: кто является active controller, в каком состоянии lags, и почему подкоманда describe должна быть первой командой при расследовании проблем с метаданными.

Референсные ссылки

Все уроки курса

Тема Ссылка
1 Установка Kafka с Zookeeper https://bigdataschool.ru/blog/news/lesson1-kafka-zookeeper-install/
2 Установка Kafka в режиме KRaft https://bigdataschool.ru/blog/news/lesson2-kafka-kraft-install/
3 Docker KRaft. Однонодовый кластер https://bigdataschool.ru/blog/news/lesson3-kafka-docker-single/
4 Docker KRaft. 3-нодовый кластер https://bigdataschool.ru/blog/news/lesson4-kafka-docker-cluster/
5 Утилиты bin/. Переменные окружения и основы https://bigdataschool.ru/blog/news/lesson5-kafka-bin-intro/
6 kafka-topics.sh. Управление топиками https://bigdataschool.ru/blog/news/lesson6-kafka-topics/
7 kafka-console-producer.sh https://bigdataschool.ru/blog/news/lesson7-kafka-console-producer/
8 kafka-console-consumer.sh https://bigdataschool.ru/blog/news/lesson8-kafka-console-consumer/
9 kafka-server-start.sh / kafka-server-stop.sh https://bigdataschool.ru/blog/news/lesson9-kafka-server-start-stop/
10 kafka-storage.sh https://bigdataschool.ru/blog/news/lesson10-kafka-storage/
11 kafka-cluster.sh https://bigdataschool.ru/blog/news/lesson11-kafka-cluster/
12 kafka-metadata-quorum.sh https://bigdataschool.ru/blog/news/lesson12-kafka-metadata-quorum/
13 kafka-metadata-shell.sh https://bigdataschool.ru/blog/news/lesson13-kafka-metadata-shell/
14 kafka-features.sh https://bigdataschool.ru/blog/news/lesson14-kafka-features/
15 kafka-configs.sh https://bigdataschool.ru/blog/news/lesson15-kafka-configs/
16 kafka-log-dirs.sh https://bigdataschool.ru/blog/news/lesson16-kafka-log-dirs/
17 kafka-dump-log.sh https://bigdataschool.ru/blog/news/lesson17-kafka-dump-log/
18 kafka-delete-records.sh https://bigdataschool.ru/blog/news/lesson18-kafka-delete-records/
19 kafka-consumer-groups.sh https://bigdataschool.ru/blog/news/lesson19-kafka-consumer-groups/
20 kafka-streams-application-reset.sh https://bigdataschool.ru/blog/news/lesson20-kafka-streams-reset/
21 kafka-leader-election.sh https://bigdataschool.ru/blog/news/lesson21-kafka-leader-election/
22 kafka-reassign-partitions.sh https://bigdataschool.ru/blog/news/lesson22-kafka-reassign-partitions/
23 kafka-replica-verification.sh https://bigdataschool.ru/blog/news/lesson23-kafka-replica-verification/
24 kafka-acls.sh https://bigdataschool.ru/blog/news/lesson24-kafka-acls/
25 kafka-broker-api-versions.sh https://bigdataschool.ru/blog/news/lesson25-kafka-broker-api-versions/
26 kafka-get-offsets.sh https://bigdataschool.ru/blog/news/lesson26-kafka-get-offsets/
27 kafka-verifiable-producer/consumer.sh https://bigdataschool.ru/blog/news/lesson27-kafka-verifiable/
28 kafka-producer-perf-test.sh https://bigdataschool.ru/blog/news/lesson28-kafka-producer-perf/
29 kafka-consumer-perf-test.sh https://bigdataschool.ru/blog/news/lesson29-kafka-consumer-perf/
30 kafka-mirror-maker.sh https://bigdataschool.ru/blog/news/lesson30-kafka-mirror-maker/
31 connect-standalone.sh https://bigdataschool.ru/blog/news/lesson31-kafka-connect-standalone/
32 connect-distributed.sh https://bigdataschool.ru/blog/news/lesson32-kafka-connect-distributed/
33 kcat. Альтернативный CLI https://bigdataschool.ru/blog/news/lesson33-kcat/