1. Архитектура Kafka: топики, партиции, оффсеты и Event-Driven подход
Архитектура Kafka: топики, партиции, оффсеты и Event-Driven подход
Добро пожаловать в курс. Мы начинаем с фундамента. На собеседовании по Go (особенно на позиции Middle/Senior) вопросы по Kafka — это стандарт де-факто. Интервьюер не просто хочет узнать, умеете ли вы читать из топика, ему важно, понимаете ли вы, как Kafka обеспечивает высокую пропускную способность и гарантии доставки.
В этой статье мы разберем архитектуру Kafka «под капотом» и поймем, почему она идеально ложится на модель конкурентности Go.
Event-Driven Architecture (EDA) и место Kafka в ней
Прежде чем говорить о байтах, определимся с парадигмой. Kafka — это не просто «очередь» (как RabbitMQ), это платформа потоковой передачи событий.
На собеседовании часто спрашивают: «В чем разница между сообщением (Message) и событием (Event)?».
* Сообщение (Message) — это команда. Отправитель знает получателя и ожидает действия. Пример: «Отправь email пользователю X». * Событие (Event) — это факт того, что что-то произошло. Отправитель (Producer) не знает, кто и как будет это обрабатывать. Пример: «Пользователь X зарегистрировался».
В EDA-архитектуре сервисы слабо связаны. Один сервис публикует факт, другие реагируют. Kafka выступает здесь как центральный нервный узел, хранящий историю событий bigdataschool.ru.
Анатомия Kafka: Брокеры, Кластеры и Zookeeper/KRaft
Физически Kafka — это распределенная система.
* Брокер (Broker) — это один сервер (узeл) Kafka. Он принимает сообщения, записывает их на диск и отдает потребителям. * Кластер (Cluster) — группа брокеров, работающих вместе. * Контроллер — мозг кластера. Раньше для координации использовался Zookeeper, но современные версии переходят на протокол KRaft (Kafka Raft Metadata mode), избавляясь от внешней зависимости.
Логическая структура: Топик и Партиция
Здесь начинается самое важное для разработчика.
Топик (Topic)
Топик — это логическая категория, поток данных с определенным именем. Можно представить его как папку в файловой системе. В топик «orders» падают заказы, в «logs» — логи.Партиция (Partition)
Топик слишком велик, чтобы храниться на одном сервере целиком. Поэтому Kafka разбивает топик на части — партиции.!Топик разбивается на партиции, которые распределяются по брокерам для масштабирования
Партиция — это фундаментальная единица масштабирования и параллелизма в Kafka.
Внутри партиции каждое сообщение получает уникальный порядковый номер — Offset (смещение). Партиция — это упорядоченный, неизменяемый (immutable) лог событий. Новые сообщения всегда добавляются в конец (append-only).
> Важно для собеседования: Kafka гарантирует порядок сообщений ТОЛЬКО в рамках одной партиции. Глобального порядка в топике не существует.
Если вам нужно, чтобы все события по конкретному user_id обрабатывались в строгом порядке, вы должны гарантировать, что они попадут в одну и ту же партицию. Это делается с помощью ключа сообщения (Key) habr.com.
Структура сообщения (Record)
Каждая запись в Kafka состоит из: * Key (Ключ): (опционально) определяет, в какую партицию попадет сообщение. * Value (Значение): сама полезная нагрузка (обычно JSON, Avro, Protobuf). * Timestamp: время события. * Headers: метаданные.Оффсеты (Offsets): Как мы читаем данные
В отличие от классических очередей (RabbitMQ, SQS), чтение сообщения в Kafka не удаляет его. Сообщение остается на диске до истечения срока хранения (Retention Policy).
Offset — это просто число, указывающее, на каком месте в партиции остановился конкретный потребитель (Consumer). Это похоже на закладку в книге.
* Если Consumer упал и перезапустился, он читает свой последний сохраненный (committed) оффсет и продолжает с него. * Вы можете «перемотать» оффсет назад и перечитать данные заново (Replayability) — это киллер-фича Kafka.
Масштабирование: Consumer Groups
Как читать данные быстро? Запустить много инстансов вашего Go-сервиса. В Kafka это объединяется понятием Consumer Group.
Правило масштабирования описывается формулой:
где — количество активных консьюмеров в одной группе, а — количество партиций в топике.
Пояснение: Kafka назначает каждую партицию только одному консьюмеру внутри группы. Это гарантирует, что одно сообщение не будет обработано дважды разными инстансами одной группы.
* Если у вас 4 партиции и 2 консьюмера -> каждый читает по 2 партиции. * Если у вас 4 партиции и 4 консьюмера -> каждый читает по 1 партиции (идеальный баланс). * Если у вас 4 партиции и 5 консьюмеров -> один консьюмер будет простаивать (idle).
Для Go-разработчика это означает, что параллелизм обработки (количество горутин-воркеров) ограничен количеством партиций на уровне архитектуры топика.
Репликация и отказоустойчивость
Чтобы данные не пропали при падении брокера, партиции реплицируются.
* Leader Replica: отвечает за все операции чтения и записи. * Follower Replicas: пассивно копируют данные с лидера.
Если лидер падает, один из фолловеров (который находится в синхронном состоянии — ISR, In-Sync Replica) автоматически становится новым лидером.
Итоги
Для успешного прохождения собеседования запомните ключевые тезисы:
__consumer_offsets.