← Назад к вопросам

Из чего состоит Kafka

2.0 Middle🔥 221 комментариев
#Брокеры сообщений

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Архитектура Apache Kafka: компоненты и их взаимодействие

Apache Kafka — это распределенная потоковая платформа, которая спроектирована для обработки больших объемов данных в реальном времени с высокой пропускной способностью и низкой задержкой. Её архитектура состоит из нескольких ключевых компонентов, которые работают совместно.

Основные компоненты Kafka

1. Брокер (Broker)

Это сервер (нода) в кластере Kafka, который отвечает за хранение данных, обработку запросов на чтение/запись и поддержку репликации. Кластер Kafka обычно состоит из нескольких брокеров для обеспечения отказоустойчивости и масштабируемости.

# Пример запуска брокера Kafka (упрощённо)
bin/kafka-server-start.sh config/server.properties

Каждый брокер идентифицируется уникальным ID. Клиенты (производители и потребители) подключаются к любому из брокеров, который выступает в роли точки входа в кластер.

2. Топик (Topic)

Это логическая категория или поток сообщений. Все сообщения в Kafka организованы в топики. Например, user_actions, transaction_logs. Топики в Kafka неизменяемы — сообщения только добавляются, но не изменяются или удаляются (в рамках политик хранения).

// Создание топика через Admin API (Java)
AdminClient admin = AdminClient.create(config);
NewTopic newTopic = new NewTopic("my_topic", 3, (short) 2);
admin.createTopics(Collections.singleton(newTopic));

3. Партиция (Partition)

Каждый топик делится на одну или несколько партиций. Это механизм параллелизации: разные партиции одного топика могут обрабатываться на разных брокерах и потребляться разными потребителями.

  • Каждая партиция — это упорядоченная, неизменяемая последовательность сообщений.
  • Сообщения в партиции имеют уникальный offset (смещение) — монотонно возрастающий номер, который идентифицирует положение сообщения внутри партиции.
  • Ключ сообщения (key) определяет, в какую партицию попадёт сообщение (хешируется). Сообщения с одинаковым ключом гарантированно попадают в одну и ту же партицию, что обеспечивает порядок обработки для связанных сообщений.

4. Реплика (Replica)

Для обеспечения отказоустойчивости каждая партиция реплицируется на несколько брокеров.

  • Лидер (Leader Replica): Одна из реплик является лидером. Все операции чтения и записи для данной партиции идут через лидера.
  • Последователь (Follower Replica): Остальные реплики являются последователями. Они постоянно асинхронно или синхронно (в зависимости от конфигурации) копируют данные с лидера. Если лидер выходит из строя, один из последователей становится новым лидером (процесс переизбрания лидера).

5. ZooKeeper / KRaft (Контроллер)

Исторически Kafka зависела от Apache ZooKeeper для управления кластером:

  • Выбор лидера партиций.
  • Отслеживание состояния брокеров (жив/мёртв).
  • Хранение конфигураций топиков и ACL (списков контроля доступа).

Современные версии Kafka (3.3+) постепенно переходят на KRaft — встроенный консенсус-протокол на основе Raft. В режиме KRafka роль управления кластером выполняет выделенный контроллер (Controller) — специальный брокер, избранный внутри кластера, который принимает метаданные и управляет состояниями. Это устраняет внешнюю зависимость от ZooKeeper, упрощая архитектуру и повышая надёжность.

6. Производитель (Producer)

Приложение, которое публикует (пишет) данные в топики Kafka.

  • Определяет, в какую партицию отправить сообщение (на основе ключа или рандомно).
  • Может использовать подтверждения (acks) для гарантии доставки: acks=0 (нет гарантий), acks=1 (только лидер подтвердил), acks=all (лидер и все синхронные реплики подтвердили).
  • Имеет буфер в памяти и может использовать батчирование для повышения эффективности.
// Пример производителя на Go (sarama клиент)
producer, _ := sarama.NewSyncProducer([]string{"broker:9092"}, config)
msg := &sarama.ProducerMessage{
    Topic: "orders",
    Key:   sarama.StringEncoder("user_123"),
    Value: sarama.StringEncoder("New order placed"),
}
partition, offset, _ := producer.SendMessage(msg)

7. Потребитель (Consumer)

Приложение, которое читает (подписывается) данные из топиков Kafka.

  • Потребители объединяются в группы потребителей (Consumer Group).
  • Каждая партиция топика в конкретный момент времени потребляется только одним потребителем из группы, что обеспечивает параллельную обработку и балансировку нагрузки.
  • Потребитель сам управляет своим смещением (offset), отмечая, какие сообщения уже обработаны. Смещения могут храниться во внутреннем топике Kafka __consumer_offsets.

8. Consumer Group (Группа потребителей)

Логическая группа потребителей, совместно обрабатывающих один или несколько топиков.

  • Групповой координатор (Group Coordinator) (один из брокеров) управляет распределением партиций между потребителями группы через протокол перебалансировки (rebalance).
  • Если потребитель покидает группу или добавляется новый, происходит перебалансировка — перераспределение партиций между оставшимися участниками.

9. Соединители (Connectors) и Kafka Connect

Готовые компоненты для интеграции Kafka с внешними системами (базы данных, S3, Elasticsearch и т.д.).

  • Source Connector: Импортирует данные из внешней системы в топик Kafka.
  • Sink Connector: Экспортирует данные из топика Kafka во внешнюю систему.
  • Kafka Connect — это отдельный сервис для запуска и управления соединителями.

10. Потоковый процессор: Kafka Streams / ksqlDB

Библиотеки для обработки данных непосредственно внутри приложений.

  • Kafka Streams: Библиотека на Java/Go для построения приложений реального времени, выполняющих операции над потоками (фильтрация, агрегация, соединение).
  • ksqlDB: Декларативный SQL-движок для обработки потоков данных в Kafka, позволяющий писать запросы, похожие на SQL.

Взаимодействие компонентов: общая схема работы

  1. Администратор создаёт топик logs с 3 партициями и фактором репликации 2 через API или утилиты.
  2. Кластер Kafka (управляемый ZooKeeper/KRaft) распределяет партиции и их реплики между доступными брокерами, выбирая лидеров.
  3. Производитель приложения-логгера отправляет сообщения с ключом service_id в топик logs. Сообщения с одним service_id попадают в одну партицию, сохраняя порядок.
  4. Группа потребителей из 2-х инстансов приложения-анализатора подписывается на топик logs. Групповой координатор назначает, например, 2 партиции первому потребителю и 1 партицию — второму.
  5. Потребители читают сообщения, обрабатывают их и коммитят (подтверждают) смещения.
  6. При падении одного из брокеров контроллер инициирует выбор нового лидера для партиций, лидером которых он был, и перебалансировку групп потребителей. Работа кластера продолжается с минимальными потерями (при правильных настройках acks и min.insync.replicas).

Таким образом, Kafka представляет собой сложную, но элегантную децентрализованную систему, где компоненты отвечают за хранение, отказоустойчивость, передачу и обработку потоков данных, обеспечивая высокую производительность и надёжность, необходимые для современных data-driven приложений.