Kafka: проверка работоспособности кластера
Kafka-кластер в KRaft-режиме не прощает, когда о нём забывают до первого инцидента. Проверять здоровье нужно регулярно и короткими командами — без графиков и дашбордов, прямо из консоли. Ниже — набор команд, которые закрывают типовой чек-лист: процессы, кворум, лидеры партиций, ISR и быстрый «светофор» одним вызовом.
Проверка процессов KRaft
В режиме KRaft отдельного ZooKeeper нет, и роль controller совмещена с ролью broker или вынесена на отдельные ноды. Сначала убедимся, что JVM-процессы вообще живы, и посмотрим, в каком режиме стартовал каждый узел.
Для управляемого кластера ожидаемо увидеть три процесса QuorumControllerMain на выделенных контроллерах и N процессов kafka.Kafka на брокерах. На смешанных нодах (combined mode) будет один процесс сразу с двумя ролями — это нормально для небольших инсталляций.
Дальше — журнал запуска и конфигурация:
Параметр process.roles принимает значения broker, controller или broker,controller. Если в нём пусто — кластер ещё в legacy-режиме с ZooKeeper, и команды ниже нужно адаптировать.
Проверяем, что все ноды договорились о кворуме:
В выводе ищем leaderId, votedLeaders и размер кворума 2/3 (для трёх контроллеров) или N/N для уже стабилизированного кластера.
Статусы брокеров и контроллера
Дальше — понять, кто из брокеров реально отвечает, а кто выпал из реестра. Используем kafka-broker-api-versions.sh: он возвращает поддерживаемые API-версии и попутно показывает, доходит ли TCP-соединение до брокера.
Если узел недоступен — увидим таймаут. Это самый быстрый способ отличить «брокер висит в JVM» от «сеть режет».
Полный список зарегистрированных брокеров и их состояние:
Команда покажет JSON-like листинг, но для табличного отчёта удобнее kafka-metadata-quorum.sh:
Колонка LEADER показывает текущий лидер кворума, REPLICAS — все активные узлы. Контроллеры, не отвечающие на запрос, выпадут из списка.
Поле lastCaughtUpTime в выводе describe --status показывает, насколько контроллер отстал от лидера. Значение 0 или свежее now — здоров, отставание в минутах — повод смотреть GC и сетевые задержки.
Список топиков и partition leaders
Кластер может быть жив, но без лидеров партиций — продюсер не запишет, консьюмер не прочитает. Поэтому следующий шаг — топики и их лидеры.
Список всех топиков с количеством партиций и реплик:
Таблица вывода содержит Leader, Replicas, Isr. Если Leader равен -1, значит, партиция не имеет активного лидера — это авария, продюсеры будут получать NotLeaderForPartitionException.
Чтобы получить только «плохие» партиции в одном пайпе:
Если хочется видеть лидеров по конкретному топику:
ISR и недоступные реплики
ISR (in-sync replicas) — это то, что определяет надёжность записи. Рекомендуется держать min.insync.replicas >= 2 для критичных топиков. Проверяем рассинхрон:
Команда вернёт партиции, у которых Isr меньше, чем Replicas. Пустой вывод — хорошо. Любая строка в списке — инцидент.
Полная картина по всем партициям с фильтром по проблемам:
kafka-topics.sh --describe для топика с тысячами партиций выводит много строк и нагружает контроллер. На проде запускайте с --partitions N или фильтруйте awk, иначе чек сам станет источником проблемы.
Дополнительно — состояние конкретной реплики на стороне брокера. Если подозреваем, что один из дисков отстал:
В выводе смотрим поле partition.error — если оно непустое, реплика имеет проблемы (offline log dir, диск переполнен, fs в read-only).
Быстрая диагностика в одной команде
Для ежедневных обходов удобно собрать все проверки в одном скрипте с понятными exit-кодами. Ниже — минимальный «светофор» на bash.
Сохраняем как kafka-health.sh, делаем исполняемым и заворачиваем в cron или systemd timer раз в 60 секунд:
Для алертинга замените блок echo на logger -p local0.err и настройте rsyslog в SIEM. Так Prometheus node_exporter не нужен — события летят в общий канал.
Типичные ошибки при первом прогоне и как их трактовать:
| Симптом | Вероятная причина | Что делать |
|---|---|---|
Connection to node -1 could not be established | Брокер не зарегистрирован в кластере, но процесс жив | Проверить advertised.listeners, node.id, сетевой ACL |
isLeader: false у всех контроллеров | Потерян кворум, контроллеров < __.min.insync.replicas | Смотреть controller.quorum.voters и состояние дисков на контроллерах |
--under-replicated-partitions показывает записи дольше 5 минут | Брокер отстаёт, диск медленный или GC-паузы | Снять jstack, проверить iostat -x и метрики LogFlushRate |
kafka-log-dirs.sh возвращает LogDirOffline | Диск переполнен или вышел из строя | Освободить место, проверить ФС на read-only, рестартовать брокер |
Пустой вывод --describe при работающем кластере | Передан неверный bootstrap-адрес | Сверить advertised.listeners и DNS |
Пять команд выше покрывают 90% оперативных вопросов «а кластер живой?». Если все зелёные — копать глубже не нужно; если что-то красное — kafka-log-dirs.sh и kafka-metadata-quorum.sh describe --status покажут, в какую сторону двигаться.