ADG Оставить заявку
Блог Данные и аналитика 4 мин чтения

Apache Kafka 3.1 и KRaft: разворачиваем кластер без ZooKeeper в продакшне

KRaft-режим Kafka 3.1 рекомендован для новых продакшн-установок. Разворачиваем тестовый кластер, убираем ZooKeeper из схемы и проверяем совместимость с существующими producer/consumer.

Контекст момента

Apache Kafka 3.1 (январь 2022): KRaft-режим достиг production-ready для новых кластеров без ZooKeeper

ZooKeeper в Kafka-стеке - это отдельный разговор. Не потому что он плохой, а потому что каждый, кто хоть раз поднимал Kafka в продакшне, знает: у тебя теперь два кластера вместо одного. Kafka-брокеры + ZooKeeper-ансамбль. Отдельный мониторинг, отдельная конфигурация, отдельные точки отказа. Kafka 3.1, вышедшая в январе, объявила KRaft-режим production-ready для новых установок - и мы решили разобраться, что это значит на практике.

Что такое KRaft и почему это важно

KRaft (Kafka Raft Metadata mode) - это реализация консенсусного протокола Raft прямо внутри Kafka, без ZooKeeper. Идея простая: Kafka сама хранит метаданные о топиках, партициях и брокерах, используя внутренний лог и кворум контроллеров.

До версии 3.1 KRaft был помечен как экспериментальный. Теперь Apache-проект официально рекомендует его для новых продакшн-кластеров. Важная оговорка: для миграции существующих кластеров с ZooKeeper инструментарий ещё не готов - речь именно про новые установки.

Что меняется архитектурно:

  • Без ZooKeeper. Три-пять нод ансамбля ZooKeeper уходят из схемы. Один тип инфраструктуры вместо двух.
  • KRaft-контроллеры. Выделенные контроллер-ноды (или совмещённые broker+controller) хранят метаданные в специальном топике __cluster_metadata.
  • Быстрее восстановление после сбоя. ZooKeeper-режим при перезапуске читал метаданные из ZooKeeper нелинейно; KRaft реплицирует их как обычный лог.

Разворачиваем тестовый кластер 3.1

Взяли три ноды: каждая работает в режиме broker+controller (роль broker,controller в конфиге). Это допустимо для небольших кластеров - для крупных имеет смысл разделить роли.

Ключевые параметры server.properties:

process.roles=broker,controller
node.id=1
controller.quorum.voters=1@node1:9093,2@node2:9093,3@node3:9093
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
inter.broker.listener.name=PLAINTEXT
controller.listener.names=CONTROLLER
log.dirs=/var/kafka/data

Перед первым стартом обязательно генерируем кластерный UUID и форматируем хранилище:

KAFKA_CLUSTER_ID=$(kafka-storage.sh random-uuid)
kafka-storage.sh format -t $KAFKA_CLUSTER_ID -c server.properties

Этот шаг обязателен - без форматирования брокеры не поднимутся. UUID должен быть одинаковым на всех трёх нодах.

Проверяем совместимость producer/consumer

Тут была главная часть упражнения. У нас есть несколько pipeline'ов, которые пишут в Kafka и читают из неё: инжест событий из нескольких источников, потоковая обработка через Kafka Streams, чтение в ClickHouse через kafka-движок.

Результат: producer и consumer не заметили разницы. Клиентский протокол Kafka не изменился - KRaft это изменение внутри кластера, не на уровне API. Java-клиенты версий 2.x и 3.x работают без каких-либо изменений в конфигурации приложений. ClickHouse kafka-движок тоже подключился без вопросов - он работает через стандартный Kafka-протокол.

Единственное, на что нужно обратить внимание: в новом кластере нет zookeeper.connect в конфиге брокеров, и если у вас есть клиентский код, который явно обращается к ZooKeeper (старые скрипты, legacy-утилиты), он, понятно, работать не будет. Но это и есть суть изменения.

Операционные наблюдения

Несколько вещей, которые стоит знать до того, как идти в продакшн.

Инструменты. Часть административных утилит Kafka ещё имеет аргументы --zookeeper. В KRaft-режиме они не работают, нужно использовать --bootstrap-server. Большинство современных утилит уже поддерживают оба варианта, но старые скрипты придётся пересмотреть.

Метрики. ZooKeeper-специфичные метрики, которые были в мониторинге, становятся неактуальными. Вместо них смотрим на метрики контроллера: kafka.controller:type=KafkaController,name=ActiveControllerCount и связанные. Grafana-дашборды для KRaft-кластеров пока менее распространены - пришлось адаптировать существующий.

Логи. В KRaft-режиме активнее используется __cluster_metadata топик. Его нужно мониторить как любой системный топик - не трогать руками и следить за репликацией.

Кворум контроллеров. Три контроллера - минимум для отказоустойчивости. При потере одного из трёх кластер продолжает работать, при потере двух - нет. Это то же поведение, что у ZooKeeper-ансамбля.

Где сейчас

Тестовый кластер 3.1 в KRaft-режиме работает вторую неделю. Нагрузку гоняли близкую к продакшновой: несколько тысяч сообщений в секунду, несколько топиков, consumer groups. Проблем не обнаружили.

Для существующих продакшн-кластеров на ZooKeeper менять ничего не будем - нет инструмента миграции, нет и смысла рисковать. Но следующий новый кластер для аналитической инфраструктуры поднимем уже на KRaft: схема стала проще, и это само по себе веский аргумент.

Надо отметить, что ClickHouse в апреле сделал похожий шаг со своим Keeper - тоже убирает ZooKeeper из стека, но другим способом. Тренд понятен: зависимость от ZooKeeper в стриминговых и аналитических системах постепенно уходит.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.