Автор статьи: Сергей Прощаев (@sproshchaev)
Руководитель направления Java‑разработки в FinTech и преподаватель курса Microservice Architecture в Otus
Введение
Apache Kafka — один из самых популярных распределенных систем потоковой передачи данных. Исторически Kafka использовала Apache ZooKeeper для управления кластером, но с версии 2.8.0 появилась альтернатива — KRaft (Kafka Raft Metadata mode).
В этой статье мы подробно рассмотрим оба подхода, их преимущества и недостатки, а также поможем выбрать правильный путь для вашего проекта в микросервисной архитектуре.
И, чтобы статья была практико-ориентированной, мы рассмотрим примеры того, как можно поднять в Docker оба варианта кластера.
Что такое ZooKeeper и зачем он нужен в Kafka?
Роль ZooKeeper в традиционной Kafka ZooKeeper — это централизованный сервис для поддержания конфигурации информации, именования, обеспечения распределенной синхронизации и предоставления групповых сервисов. В традиционной Kafka ZooKeeper отвечает за:
Хранение метаданных кластера
Координацию контроллеров (controller coordination)
Отслеживание живости брокеров (broker liveness)
Управление ACL (Access Control Lists)
Хранение конфигурации топиков и брокеров
Что такое KRaft (Kafka Raft Metadata mode)?
KRaft — это сокращение от Kafka Raft, и это новая архитектура, в которой Kafka сама управляет своими метаданными, используя протокол Raft для обеспечения консистентности и отказоустойчивости. Протокол Raft, разработанный в 2014 году, стал альтернативой более сложному протоколу Paxos и стал стандартом для многих современных распределенных систем, включая etcd, Consul и другие.
В KRaft режиме Kafka брокеры берут на себя ответственность за управление метаданными. Некоторые брокеры становятся контроллерами и образуют кворум, используя протокол Raft для согласования изменений метаданных. Это означает, что теперь Kafka может управлять собой без внешней зависимости, что значительно упрощает архитектуру и улучшает производительность.
Ключевое отличие KRaft в том, что теперь все метаданные хранятся непосредственно в Kafka, и брокеры могут читать эти метаданные напрямую, без необходимости обращаться к внешней системе. Это устраняет дополнительный сетевой вызов и уменьшает задержки, особенно при частых изменениях конфигурации или при выборах контроллера.
Сравнение ZooKeeper и KRaft: подробный анализ
На рис. 1 изображены схемы двух вариантов развертывания кластера Apache Kafka в первом случае используется Zookeeper, во втором используется KRaft.

Далее мы рассмотрим эти два варианта и обсудим плюсы и минусы использования каждого.
Сложность развертывания и управления
Традиционная архитектура с ZooKeeper требует управления двумя отдельными системами. Это означает, что инженерам нужно управлять не только Kafka, но и ZooKeeper, что увеличивает сложность операций. При развертывании нужно настраивать и ZooKeeper, и Kafka, убедиться, что обе системы правильно конфигурированы и работают в согласованном состоянии.
В KRaft режиме все становится проще. Нам нужно управлять только одной системой — Kafka, которая теперь сама управляет своими метаданными. Это значительно упрощает развертывание, особенно в контейнеризированных средах, где каждая дополнительная зависимость усложняет оркестрацию.
Кроме того, в ZooKeeper‑архитектуре нужно тщательно планировать размер кластера ZooKeeper. Обычно используют 3 или 5 узлов, чтобы обеспечить кворум при отказе узлов. Это требует дополнительных ресурсов и увеличивает сложность мониторинга. В KRaft режиме мы можем использовать те же брокеры Kafka для управления метаданными, что делает архитектуру более компактной.
Производительность и задержки
Одним из ключевых преимуществ KRaft является улучшение производительности. В ZooKeeper‑режиме каждый раз, когда брокеру нужно получить или обновить метаданные, он должен обратиться к ZooKeeper, что требует сетевого вызова. Это может добавлять задержки, особенно если ZooKeeper кластер находится на другом континенте или если сеть испытывает проблемы.
В KRaft режиме метаданные хранятся непосредственно в Kafka, и брокеры могут получать к ним доступ через внутренние протоколы Kafka. Это уменьшает задержки и улучшает общую производительность системы. Также улучшается время выбора контроллера при отказах, так как теперь этот процесс происходит внутри Kafka, а не требует взаимодействия с внешней системой.
Еще один важный аспект — это масштабируемость. ZooKeeper имеет ограничения по количеству узлов и нагрузке, которые могут стать узким местом при масштабировании Kafka кластера. KRaft не имеет этих ограничений, так как использует ту же инфраструктуру, что и сама Kafka.
Надежность и отказоустойчивость
ZooKeeper‑архитектура имеет определенные риски. ZooKeeper сам по себе может стать точкой отказа, особенно если кластер ZooKeeper маленький или неправильно сконфигурирован. Если ZooKeeper недоступен, Kafka может продолжать работать с уже известными метаданными, но не сможет обрабатывать изменения конфигурации, выборы контроллера и другие операции, требующие взаимодействия с ZooKeeper.
KRaft решает эту проблему, интегрируя управление метаданными в саму Kafka. Теперь у нас есть распределенная система управления метаданными, которая использует тот же протокол Raft, что и другие распределенные системы. Это делает систему более устойчивой к отказам, так как теперь у нас нет отдельной точки отказа.
Однако стоит отметить, что KRaft — более молодая технология, и хотя она прошла тщательное тестирование, она не имеет такого же долгого времени работы в продакшене, как ZooKeeper. Это может быть важным фактором для критически важных систем, где стабильность и проверенное время существование являются приоритетом.
Преимущества и недостатки каждого подхода
ZooKeeper
Одним из самых значительных преимуществ ZooKeeper является его зрелость и проверенное время существование. ZooKeeper используется в производстве уже более 15 лет, и за это время было накоплено огромное количество знаний, практик и решений проблем. Это особенно важно для крупных организаций, где стабильность и надежность превыше всего.
Зрелость ZooKeeper также означает, что есть обширная документация, множество учебных материалов, активные сообщества и опытные инженеры, которые могут помочь в случае проблем. Это создает определенную уверенность в том, что любые проблемы, которые могут возникнуть, уже были решены кем‑то раньше.
Отделение ответственности в ZooKeeper‑архитектуре также имеет свои преимущества. Поскольку ZooKeeper отвечает только за координацию, а Kafka — за хранение данных, каждая система может быть оптимизирована для своей конкретной задачи. Это может привести к лучшей производительности в определенных сценариях, особенно если у вас есть специфические требования к управлению метаданными.
Еще одним важным преимуществом является возможность использования ZooKeeper для других сервисов в вашей инфраструктуре. Если у вас уже есть ZooKeeper кластер, используемый для других целей, интеграция Kafka с ним может быть логичным продолжением вашей архитектуры.
ZooKeeper: Понимание недостатков
Несмотря на все преимущества, ZooKeeper имеет и свои недостатки, которые становятся более очевидными по мере роста сложности систем. Основной недостаток — это сложность операций. Управление двумя отдельными системами требует больше времени, знаний и ресурсов. Каждая система имеет свои метрики, логи, конфигурации и особенности, что увеличивает когнитивную нагрузку на инженеров.
Дополнительные ресурсы, необходимые для ZooKeeper, также являются важным фактором. Кластер ZooKeeper требует отдельных серверов, памяти, CPU и дискового пространства. Эти ресурсы не работают на прямую обработку данных Kafka, а только на координацию, что может быть неэффективным с точки зрения использования ресурсов.
Ограничения масштабируемости ZooKeeper также могут стать проблемой. ZooKeeper не предназначен для хранения больших объемов данных или обработки высокой нагрузки. При масштабировании Kafka кластера, особенно при большом количестве топиков и партиций, ZooKeeper может стать узким местом.
KRaft
KRaft представляет собой современный подход к архитектуре Kafka, и его главное преимущество — это упрощенная архитектура. Вместо управления двумя системами, теперь нужно управлять только одной. Это значительно упрощает развертывание, особенно в контейнеризированных и облачных средах, где каждая дополнительная зависимость усложняет оркестрацию.
Улучшенная производительность — еще одно важное преимущество KRaft. Поскольку метаданные теперь хранятся непосредственно в Kafka, задержки при доступе к метаданным значительно снижаются. Это особенно важно для сценариев с частыми изменениями конфигурации или высокой частотой выборов контроллера.
Упрощенное управление также является значительным преимуществом. Теперь у нас есть единая система для мониторинга, логирования и отладки. Это снижает когнитивную нагрузку на инженеров и упрощает операции.
KRaft: Понимание недостатков
Несмотря на все преимущества, KRaft имеет и свои недостатки. Основной из них — это относительная новизна технологии. Хотя KRaft прошел тщательное тестирование, он не имеет такого же долгого времени работы в продакшене, как ZooKeeper. Это может быть важным фактором для организаций, которые предпочитают проверенные решения.
Процесс миграции с ZooKeeper на KRaft также может быть сложным. Хотя Apache Kafka предоставляет инструменты для миграции, это все еще требует тщательного планирования, тестирования и может сопровождаться рисками. Некоторые инструменты и интеграции могут не поддерживать KRaft сразу, что требует дополнительной работы по обновлению экосистемы.
Практические примеры конфигурации и развертывания
Для лучшего понимания различий между двумя подходами, давайте рассмотрим, как выглядит конфигурация в каждом случае.
Для этого воспользуемся примером развертывания кластера в двух вариантах:
В ZooKeeper‑режиме мы видим, что основной акцент делается на соединении с ZooKeeper кластером. Конфигурация брокера содержит параметры, указывающие на ZooKeeper, и брокер полагается на ZooKeeper для получения информации о состоянии кластера.
В KRaft режиме картина полностью меняется. Теперь брокеры сами участвуют в управлении метаданными, и конфигурация отражает это. Мы видим параметры, определяющие роль брокера (контроллер, брокер или обе роли), список голосующих узлов для кворума и другие параметры, специфичные для протокола Raft.
Рекомендации по выбору подхода
При выборе между ZooKeeper и KRaft важно учитывать несколько факторов. Если вы начинаете новый проект, KRaft обычно является лучшим выбором. Это современное решение, которое проще в управлении и имеет лучшую производительность. Также KRaft является будущим Kafka, и в долгосрочной перспективе ZooKeeper будет постепенно устаревать.
Если у вас уже есть работающий Kafka кластер на ZooKeeper, решение о миграции требует тщательного анализа. Необходимо оценить риски, время, необходимое для миграции, и потенциальные выгоды. В некоторых случаях имеет смысл оставаться на ZooKeeper, особенно если у вас критически важные системы, где стабильность превыше всего.
Для организаций, которые уже используют ZooKeeper для других сервисов, может быть логичным продолжать использовать ZooKeeper и для Kafka, чтобы избежать дублирования инфраструктуры. Однако в долгосрочной перспективе переход на KRaft может привести к более простой и эффективной архитектуре.
Практические советы и лучшие практики
При работе с ZooKeeper‑режимом особенно важно правильно настроить кластер ZooKeeper. Рекомендуется использовать нечетное количество узлов (3, 5 или 7) для обеспечения кворума при отказах. Также важно правильно настроить параметры ZooKeeper, такие как tickTime, initLimit и syncLimit, в зависимости от характеристик вашей сети и требований к задержкам.
Для KRaft режима важно правильно спланировать распределение ролей между брокерами. Не все брокеры должны быть контроллерами, но важно обеспечить достаточное количество контроллеров для отказоустойчивости. Также важно правильно настроить параметры Raft, такие как время ожидания голосования и размер буфера.
В обоих случаях мониторинг играет ключевую роль. В ZooKeeper‑режиме нужно мониторить как Kafka, так и ZooKeeper, отслеживая метрики производительности, задержки и состояния кластера. В KRaft режиме мониторинг упрощается, но все равно требует внимания к метрикам, связанным с Raft и управлением метаданными.
Заключение
Выбор между ZooKeeper и KRaft — это не просто техническое решение, а стратегическое решение, которое повлияет на вашу инфраструктуру на годы вперед. ZooKeeper предлагает проверенную стабильность и зрелую экосистему, но требует более сложного управления и дополнительных ресурсов. KRaft предоставляет современную, упрощенную архитектуру с лучшей производительностью, но требует осторожного подхода к миграции и имеет меньший опыт использования в продакшене.
Для новых проектов KRaft обычно является предпочтительным выбором, так как это будущее Kafka. Для существующих систем решение должно основываться на конкретных требованиях, рисках и стратегии развития. В любом случае, понимание различий между этими подходами позволяет принимать более обоснованные решения и строить более надежные и эффективные системы потоковой обработки данных.
Если вы работаете с распределёнными системами и интересуетесь архитектурными подходами вроде Kafka с ZooKeeper или KRaft, следующий шаг — глубже разобраться в принципах построения сервисов. На курсе Microservice Architecture мы разбираем практические аспекты проектирования и сопровождения микросервисов: от взаимодействия сервисов и интеграционных паттернов до вопросов отказоустойчивости и масштабирования.
Пройдите вступительный тест, чтобы узнать, подойдет ли вам программа курса.
На странице курса сейчас можно записаться на бесплатные открытые уроки.