Брокеры, Топики, Партиции
Первый урок дал ментальную модель — commit log. Теперь разберём физическую реальность: как этот commit log существует в кластере из нескольких машин. Ответ — через три уровня абстракции: брокеры, топики и партиции.
Брокер: JVM-процесс, хранящий данные
Брокер (broker) — это отдельный серверный процесс Kafka (JVM). Каждый брокер идентифицируется числовым node.id. В кластере брокеры взаимодействуют через KRaft-протокол (Kafka 4.0+).
Ключевые конфигурационные свойства брокера:
# node.id — уникальный числовой идентификатор в кластере
node.id=1
# process.roles — роль в кластере
# broker: обслуживает producers и consumers, хранит данные
# controller: участвует в KRaft quorum (metadata management)
# combined: и то и другое (типично для dev/small clusters)
process.roles=broker,controller
# listeners — адреса и протоколы
listeners=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
advertised.listeners=PLAINTEXT://broker1.example.com:9092
# log.dirs — где брокер хранит данные партиций
log.dirs=/var/kafka/logs
В production-кластере типично разделяют роли: 3 dedicated controller-узла + N broker-узлов. В Kafka 4.0 брокер с process.roles=broker не участвует в quorum — он только хранит данные и обслуживает клиентов. Контроллеры с process.roles=controller не хранят пользовательские данные.
В Kafka 4.0 все конфигурационные файлы находятся в config/ (не в config/kraft/ как в Kafka 3.x). KRaft — единственный режим: KAFKA_ZOOKEEPER_CONNECT не существует как переменная среды в официальном образе apache/kafka:4.0.0.
Топик: именованный поток событий
Топик — это логическое пространство имён для событий одного типа. orders, payments, user-sessions, inventory-updates — всё это топики.
Создание топика через CLI:
# Kafka 4.0: только --bootstrap-server, не --zookeeper
kafka-topics.sh \
--create \
--topic orders \
--partitions 6 \
--replication-factor 3 \
--bootstrap-server localhost:9092
Важнейшие параметры топика:
| Параметр | Что задаёт | Типичное значение |
|---|---|---|
--partitions | Степень параллелизма и масштаб хранения | 6–48 для production |
--replication-factor | Сколько копий каждой партиции в кластере | 3 (не больше числа брокеров) |
retention.ms | Как долго хранить данные | 604800000 (7 дней) |
cleanup.policy | delete (удаление по retention) или compact (дедупликация по ключу) | delete |
Просмотр конфигурации топика:
kafka-topics.sh \
--describe \
--topic orders \
--bootstrap-server localhost:9092
Вывод покажет: PartitionCount, ReplicationFactor, лидеров и реплики каждой партиции, список ISR (In-Sync Replicas).
Партиция: единица параллелизма и упорядоченности
Партиция — физическая единица хранения и параллелизма. Топик orders с --partitions 6 создаёт шесть отдельных append-only логов: orders-0, orders-1, …, orders-5.
Три свойства партиций, которые нужно понять:
1. Упорядоченность внутри партиции. Kafka гарантирует порядок записей строго внутри одной партиции. Между партициями порядок не гарантирован. Если порядок важен, используйте ключ сообщения: продюсер хэширует ключ и всегда направляет сообщения с одинаковым ключом в одну партицию.
# Python kafka-python: все события одного order_id в одну партицию
producer.send(
'orders',
key=b'order-12345', # ключ → deterministic partition
value=b'{"status":"shipped"}'
)
2. Параллелизм потребления. Один consumer group может читать топик параллельно в N потоков, где N = количество партиций. Больше партиций = больше потенциальный параллелизм потребления. Но: каждую партицию читает ровно один consumer в группе. Если в группе 4 consumer, а партиций 6 — двое consumer читают по 2 партиции, двое — по 1.
3. Выбор числа партиций. Это одно из самых критичных решений при создании топика. Увеличить число партиций можно (kafka-topics.sh --alter), но уменьшить — нельзя. Правило: num.partitions >= max_consumers_in_group. Для высоконагруженных топиков: ориентируйтесь на целевую пропускную способность (MB/s) / пропускная способность одной партиции.
Не создавайте слишком много партиций. Каждая партиция — это открытый файл на диске брокера, память в heap JVM, и overhead для leader election. Кластер из 3 брокеров с 50 000 партиций работает нестабильно. Ориентир: не более 4000 партиций на брокер (Kafka 4.0 с KRaft справляется лучше, чем ZooKeeper-эра, но физические ограничения остаются).
Лидер и Фолловер: распределение нагрузки
Каждая партиция имеет ровно одну лидерскую реплику (leader) и одну или несколько фолловерских реплик (follower).
Лидер принимает все записи от продюсеров и все запросы на чтение от потребителей (по умолчанию). Это единственный контакт продюсера и потребителя с партицией.
Фолловеры не взаимодействуют с клиентами напрямую. Их единственная задача — реплицировать данные от лидера через fetch-запросы. Как только фолловер получил запись и подтвердил её хранение, он входит в ISR (In-Sync Replicas) — множество реплик, которые могут стать новым лидером.
Назначение лидеров при создании топика: KRaft-контроллер распределяет лидеров равномерно по брокерам через preferred leader assignment. Топик с 6 партициями в кластере из 3 брокеров — каждый брокер становится лидером 2 партиций.
Проверить, кто является лидером каждой партиции:
kafka-topics.sh \
--describe \
--topic orders \
--bootstrap-server localhost:9092
# Пример вывода:
# Topic: orders PartitionCount: 6 ReplicationFactor: 3
# Topic: orders Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
# Topic: orders Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
# Topic: orders Partition: 2 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2
# ...
Replication Factor: сколько копий держать
--replication-factor 3 означает: каждая запись хранится на 3 брокерах — 1 лидер + 2 фолловера.
Replication factor напрямую влияет на:
- Надёжность: при RF=3 кластер переживает потерю 2 брокеров (один за раз, с recovery между ними).
- Пропускную способность записи: продюсер ждёт подтверждения от ISR-реплик (зависит от
acks). - Использование дискового пространства: в 3 раза больше, чем при RF=1.
Минимально рекомендуемый RF для production: 3. RF=2 не рекомендуется — при потере одного брокера у вас только одна копия данных, и любая проблема с этим брокером приведёт к недоступности. RF=1 только для dev и test окружений.
Смотреть replication factor топика и текущих лидеров:
# Проверить баланс лидеров по брокерам
kafka-topics.sh \
--describe \
--topic orders \
--bootstrap-server localhost:9092 \
--report-under-replicated-partitions
# Если брокер упал — вывод покажет партиции без одной из реплик
Ключевые выводы
- Брокер — JVM-процесс с
node.id,process.roles=broker|controller|broker,controller. - Топик — именованный поток с
num.partitionsиreplication.factor. CLI:kafka-topics.sh --bootstrap-server. - Партиция — единица параллелизма и упорядоченности. Порядок гарантирован только внутри одной партиции.
- Лидер принимает записи и чтения. Фолловеры реплицируют через fetch.
- Replication factor = 3 для production. Изменение числа партиций — только увеличение, не уменьшение.