Как работает Apache Kafka?

«Как работает Apache Kafka?» — вопрос из категории Архитектура, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Apache Kafka — это распределенная, отказоустойчивая, высокопроизводительная платформа потоковой обработки данных (streaming platform), работающая по модели "издатель-подписчик" (pub-sub). Ее основное назначение — сбор, хранение и обработка потоков событий (events) в реальном времени.

Ключевые концепции и компоненты:

  • Топик (Topic): Логический канал или категория, в которую публикуются сообщения. Топик делится на партиции (partitions) для горизонтального масштабирования и параллельной обработки.
  • Производитель (Producer): Клиентское приложение, которое публикует (пишет) сообщения в топик Kafka. Оно решает, в какую партицию топика отправить сообщение (по ключу или round-robin).
  • Потребитель (Consumer): Клиентское приложение, которое подписывается на топик(и) и читает сообщения. Потребители объединяются в группы (Consumer Groups) для распределения нагрузки: каждая партиция топика читается только одним потребителем из группы.
  • Брокер (Broker): Сервер Kafka, который хранит данные топиков и обслуживает запросы производителей и потребителей. Несколько брокеров образуют кластер.
  • ZooKeeper / KRaft: Служба управления метаданными кластера (расположение брокеров, лидеры партиций). В новых версиях Kafka (с 3.3) KRaft (Kafka Raft) заменяет ZooKeeper для упрощения архитектуры.

Пример работы (Java Producer):

import org.apache.kafka.clients.producer.*;
import java.util.Properties;

public class SimpleProducer {
    public static void main(String[] args) {
        // 1. Конфигурация Producer
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092"); // Адреса брокеров
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("acks", "all"); // Гарантия доставки: ждем подтверждения от всех реплик

        // 2. Создание экземпляра Producer
        Producer<String, String> producer = new KafkaProducer<>(props);

        // 3. Отправка сообщения в топик "orders"
        ProducerRecord<String, String> record = new ProducerRecord<>(
                "orders",           // Имя топика
                "order-12345",      // Ключ (определяет партицию)
                "{ "item": "book", "qty": 2 }" // Значение (тело сообщения)
        );

        producer.send(record, (metadata, exception) -> {
            // Callback-обработчик
            if (exception == null) {
                System.out.printf("Сообщение отправлено. Топик: %s, Партиция: %d, Offset: %d%n",
                        metadata.topic(), metadata.partition(), metadata.offset());
            } else {
                exception.printStackTrace();
            }
        });

        // 4. Закрытие Producer (обязательно для освобождения ресурсов)
        producer.close();
    }
}

Преимущества Kafka:

  • Высокая пропускная способность и низкая задержка.
  • Масштабируемость: Легко добавлять брокеры и партиции.
  • Отказоустойчивость: Данные реплицируются между брокерами.
  • Долговременное хранение: Сообщения хранятся на диске configurable retention period (часы, дни, бессрочно).
  • Поддержка потоковой обработки: Интеграция с Kafka Streams, Apache Flink, Spark Streaming.