Архитектура Kafka: Основные компоненты и их роли
Изучите основополагающие элементы распределенной архитектуры потоковой передачи событий Apache Kafka. Это руководство четко объясняет роли Брокеров Kafka, Топиков, Партиций, Продюсеров, Консьюмеров и координирующую роль ZooKeeper. Узнайте, как эти компоненты взаимодействуют для обеспечения высокопроизводительной, отказоустойчивой обработки и хранения данных – это необходимые знания для любой реализации Kafka.
Архитектура Kafka: объяснение ключевых компонентов и их ролей
Архитектура Kafka может показаться запутанной на первый взгляд, потому что одна и та же система отвечает за хранение, стриминг, репликацию и отслеживание прогресса потребителей. Как только вы разделите основные части, модель становится гораздо понятнее: продюсеры записывают записи в партиции топиков, брокеры хранят эти партиции, а потребители читают записи по смещениям.
Это руководство объясняет основные компоненты Kafka и то, как они работают вместе в реальном кластере.
Брокеры: серверы Kafka
Кластер Kafka состоит из одного или нескольких брокеров. Брокер — это сервер Kafka, который хранит данные партиций и обрабатывает запросы клиентов от продюсеров и потребителей.
Когда продюсер отправляет запись, он записывает ее на брокер, который в данный момент является лидером целевой партиции. Когда потребитель читает записи, он получает их от брокера, обслуживающего эту партицию. В обычных конфигурациях каждый брокер обрабатывает множество партиций из многих топиков.
Добавление брокеров может увеличить емкость хранилища и распределить трафик, но это не решает автоматически все узкие места. Вам также нужно достаточное количество партиций, сбалансированное размещение реплик, исправные диски и достаточная пропускная способность сети.
Топики: именованные потоки записей
Топик — это именованный поток записей, например orders, payments или user_activity. Продюсеры пишут в топики, а потребители подписываются на топики.
Топик разделен на партиции. Каждая партиция — это упорядоченный журнал, доступный только для добавления. Kafka гарантирует порядок записей только в пределах одной партиции, а не всего топика.
Эта деталь важна. Если все события для одного клиента должны обрабатываться по порядку, используйте стабильный ключ, например customer_id. Стандартный партиционер Kafka использует ключ для выбора партиции, поэтому записи с одинаковым ключом обычно попадают в одну и ту же партицию.
Партиции и смещения
Каждая запись в партиции получает смещение (offset). Смещение — это число, которое идентифицирует позицию записи в этой партиции.
Например, топик с именем orders с тремя партициями может выглядеть так:
orders-0: offset 0, offset 1, offset 2
orders-1: offset 0, offset 1
orders-2: offset 0, offset 1, offset 2, offset 3
Смещения имеют значение только в пределах своей партиции. Смещение 3 в orders-2 не связано со смещением 3 в другой партиции.
Партиции обеспечивают параллелизм Kafka. Больше партиций позволяет большему количеству потребителей в одной группе потребителей работать одновременно, до одного активного потребителя на партицию в этой группе.
Репликация и лидеры
Kafka использует репликацию для обеспечения доступности данных при сбое брокера. Каждая партиция может иметь несколько реплик на разных брокерах.
Одна реплика является лидером. Продюсеры и потребители обычно общаются с лидером этой партиции. Другие реплики являются последователями. Последователи копируют данные от лидера и готовы взять на себя управление, если лидер выйдет из строя.
Коэффициент репликации определяет, сколько копий хранит Kafka. Коэффициент репликации 3 означает, что Kafka хранит три копии каждой партиции на трех брокерах, если доступно достаточное количество брокеров.
Вы можете создать топик следующим образом:
kafka-topics.sh --create \
--topic user_activity \
--bootstrap-server localhost:9092 \
--partitions 3 \
--replication-factor 3
Эта команда требует кластер как минимум с тремя брокерами. В локальной настройке с одним брокером используйте коэффициент репликации 1.
Продюсеры: приложения, которые записывают события
Продюсеры отправляют записи в топики Kafka. Запись может включать ключ, значение, временную метку и заголовки.
Сначала продюсер запрашивает у кластера метаданные, чтобы узнать, какой брокер является лидером каждой партиции. Затем он отправляет записи непосредственно нужному брокеру.
Надежность продюсера сильно зависит от таких настроек, как:
| Настройка | На что влияет |
|---|---|
acks |
Сколько подтверждений от брокера требуется, прежде чем запись будет считаться успешной |
retries |
Будет ли продюсер повторять временные сбои |
enable.idempotence |
Помогает избежать дубликатов, вызванных повторными попытками продюсера |
compression.type |
Уменьшает использование сети и диска для многих рабочих нагрузок |
Для важных данных обычно используется acks=all, потому что лидер ждет синхронизированных реплик перед подтверждением записи. Точное поведение также зависит от настроек брокера, таких как min.insync.replicas.
Потребители и группы потребителей
Потребители читают записи из топиков. Большинство производственных потребителей работают внутри группы потребителей.
В одной группе потребителей Kafka назначает каждую партицию только одному активному потребителю в данный момент. Именно так Kafka позволяет масштабировать обработку, сохраняя порядок в каждой партиции.
Например, если orders имеет три партиции, а ваш сервис имеет трех потребителей в одной группе, каждый потребитель может обрабатывать одну партицию. Если вы добавите четвертого потребителя в ту же группу, один потребитель будет бездействовать, потому что для назначения доступно только три партиции.
Разные группы потребителей получают независимое чтение. Ваш сервис биллинга и сервис аналитики могут оба читать топик orders, не отнимая записи друг у друга.
Смещения и прогресс потребителей
Потребители отслеживают прогресс, фиксируя смещения. Kafka хранит зафиксированные смещения для групп потребителей во внутреннем топике с именем __consumer_offsets.
Если потребитель выходит из строя и перезапускается, он использует зафиксированное смещение для возобновления. Время фиксации влияет на поведение обработки:
| Время фиксации | Возможный результат |
|---|---|
| Фиксация до завершения обработки | Сбой может привести к пропуску записей |
| Фиксация после завершения обработки | Сбой может привести к повторной обработке записей |
Многие системы выбирают обработку "как минимум один раз": обработать запись, затем зафиксировать смещение. Это может создавать дубликаты после сбоя, поэтому последующие записи должны быть идемпотентными, когда это возможно.
Метаданные кластера: ZooKeeper и KRaft
Старые кластеры Kafka используют Apache ZooKeeper для управления метаданными кластера и выбора контроллера. Многие существующие установки все еще работают таким образом.
Более новые развертывания Kafka могут использовать режим KRaft — встроенный кворум метаданных Kafka. В кластерах KRaft Kafka больше не зависит от ZooKeeper для управления метаданными.
Когда вы читаете старые руководства по Kafka, проверяйте, предполагают ли они ZooKeeper или KRaft. Команды, файлы конфигурации и операционные шаги могут отличаться.
Как запись перемещается через Kafka
Типичный поток записи и чтения выглядит так:
- Продюсер подключается к бутстрап-брокеру и получает метаданные.
- Продюсер выбирает партицию на основе ключа записи или стратегии партиционирования.
- Продюсер отправляет запись брокеру-лидеру этой партиции.
- Лидер добавляет запись в свой журнал, и последователи реплицируют ее.
- Лидер подтверждает запись в зависимости от настройки
acksпродюсера. - Потребитель опрашивает партицию и получает записи, начиная с текущего смещения.
- Потребитель обрабатывает записи и фиксирует смещения для своей группы потребителей.
Этот поток объясняет, почему Kafka может поддерживать как обработку в реальном времени, так и воспроизведение. Потребители не удаляют записи, когда читают их.
Хранение: Kafka хранит данные по политике
Kafka — это не традиционная очередь, где сообщение исчезает, как только один потребитель его прочитает. Kafka хранит записи на основе настроек хранения.
Общие настройки топика включают:
retention.ms=604800000
retention.bytes=10737418240
retention.ms управляет хранением на основе времени. retention.bytes управляет хранением на основе размера. Фактическая очистка также зависит от настроек сегментов и конфигурации брокера.
Некоторые топики используют сжатие журнала (log compaction) вместо или в дополнение к удалению на основе политик хранения. Сжатие сохраняет последнее значение для каждого ключа, что полезно для топиков, подобных состоянию, таких как профили пользователей или изменения конфигурации.
Что нужно запомнить
Архитектура Kafka построена вокруг партиционированных журналов. Брокеры хранят партиции, продюсеры пишут в лидеров партиций, потребители читают по смещениям, а группы потребителей распределяют работу между партициями.
Когда вы проектируете топик Kafka, думайте о порядке, количестве партиций, коэффициенте репликации, хранении и поведении групп потребителей вместе. Эти решения определяют, как ваша система масштабируется, восстанавливается после сбоев и воспроизводит старые события.