Настройка кластера Kafka с репликацией и партиционированием
В нашей практике часто встречается ситуация: три брокера запущены, топики созданы, приложение пишет — но под нагрузкой начинается: UnderReplicatedPartitions растёт, consumer lag не снижается, leader election происходит каждые несколько минут. Это не аппаратная проблема, а неверно выставленные replication.factor, min.insync.replicas и отсутствие rack-aware assignment. Всё это закладывается при начальной настройке кластера — переделывать потом дороже, чем заказать аудит под ключ. Свяжитесь с нами — мы оценим ваш проект и предложим оптимальное решение. Правильная настройка кластера снижает операционные расходы на 20–30% за счёт сокращения простоев и эффективного использования ресурсов.
Replication factor 3: почему это недостаточно
Replication factor три — необходимое, но недостаточное условие. Если три брокера стоят в одной стойке и питаются от одного PDU, при отказе питания вы теряете весь кластер разом. Kafka поддерживает rack-awareness через broker.rack в server.properties — и это нужно выставить до создания первого топика, иначе leader'ы и реплики будут распределены без учёта топологии.
# broker 1 — server.properties
broker.id=1
broker.rack=rack-a
log.dirs=/data/kafka/logs
num.partitions=6
default.replication.factor=3
min.insync.replicas=2
unclean.leader.election.enable=falseunclean.leader.election.enable=false — ключевой параметр для production. Без него Kafka может выбрать leader из out-of-sync реплики, что приведёт к потере сообщений. Да, кластер на несколько секунд станет недоступным для записи при потере ISR-кворума — но это предсказуемый сценарий, который обрабатывается на стороне producer'а через retry. Потеря данных — нет.
На стороне producer'а:
acks=all retries=3 retry.backoff.ms=500 enable.idempotence=true enable.idempotence=true автоматически выставляет acks=all и исключает дубликаты при retry. Для большинства production-сценариев это дефолт, который нужно явно включить.
Оптимальное число партиций
Популярный совет «ставьте больше партиций» — работает до определённого предела. Каждая партиция — это файловый дескриптор на каждом брокере, плюс метаданные в ZooKeeper (или KRaft). При 10 000 партиций на кластере из трёх брокеров controller failover начинает занимать десятки секунд.
Практическое правило: partitions = max(throughput_mb/s ÷ 10, consumer_count). Для топика с пропускной способностью 100 МБ/с и 8 consumer-инстансами — 10 партиций. Не 100.
Партиционирование влияет на параллелизм потребления: один consumer в группе читает одну или несколько партиций, но не меньше одной. Если партиций меньше, чем инстансов в consumer group — часть инстансов будет простаивать. Это частая проблема при горизонтальном масштабировании потребителей без предварительного планирования топологии.
Изменить число партиций у существующего топика можно:
kafka-topics.sh --bootstrap-server kafka:9092 \ --alter --topic orders \ --partitions 20 Но порядок ключей при этом нарушится — если у вас key-based partitioning и семантика «все события одного заказа в одну партицию», увеличение числа партиций требует миграции или пересоздания топика с ребалансировкой.
Как настроить rack-awareness?
Rack-awareness настраивается параметром broker.rack в server.properties на каждом брокере. После перезапуска кластера Kafka автоматически распределяет реплики так, чтобы они попадали в разные стойки. Проверить распределение можно командой:
kafka-topics.sh --bootstrap-server kafka:9092 --describe --topic orders Если все реплики одной партиции оказались в одной стойке — значит, rack-awareness не работает. Типичная причина: разные значения broker.rack или отсутствие параметра у части брокеров.
Критические метрики для мониторинга
kafka-topics.sh --describe — первый инструмент. Показывает ISR-список для каждой партиции:
kafka-topics.sh --bootstrap-server kafka:9092 \
--describe --topic orders
# Topic: orders Partition: 0 Leader: 2 Replicas: 2,1,3 Isr: 2,1
# Partition 0: ISR = [2,1], реплика 3 выпалаЕсли ISR меньше replication factor — брокер либо лежит, либо отстал. kafka-log-dirs.sh покажет размер и смещение каждой реплики. kafka-consumer-groups.sh --describe — lag по каждой партиции в consumer group.
JMX-метрики, которые нужно мониторить обязательно:
| Метрика | Порог тревоги |
|---|---|
UnderReplicatedPartitions |
> 0 в течение 30 сек |
ActiveControllerCount |
!= 1 |
OfflinePartitionsCount |
> 0 |
RequestHandlerAvgIdlePercent |
< 0.2 |
NetworkProcessorAvgIdlePercent |
< 0.3 |
RequestHandlerAvgIdlePercent < 0.2 означает, что брокер перегружен — нужно либо добавлять брокеры, либо снижать нагрузку. Это метрика, которую часто не настраивают, и потом удивляются росту latency при, казалось бы, достаточных ресурсах.
Выбор режима метаданных: KRaft или ZooKeeper
На текущий момент KRaft (Kafka Raft Metadata mode) — без ZooKeeper — стабилен с Kafka 3.3 и рекомендован для новых кластеров. Основной выигрыш: controller failover занимает секунды вместо десятков секунд (в 3-5 раз быстрее), упрощённое операционное обслуживание. ZooKeeper как зависимость уйдёт в Kafka 4.x.
Согласно документации Apache Kafka, KRaft обеспечивает более высокую надёжность и простоту.
Для миграции существующего кластера с ZooKeeper на KRaft — процедура kafka-storage.sh + kafka-metadata-migration — это отдельная задача с downtime-окном или rolling-миграцией в зависимости от версии.
Что входит в работу
Детальный аудит конфигурации кластера (broker, producer, consumer). Проектирование топологии топиков и партиционирования. Настройка rack-awareness и параметров репликации. Настройка мониторинга (Prometheus + Grafana) с критическими алертами. Документация по эксплуатации и runbook для аварийных ситуаций. Обучение команды (1-2 сессии). Поддержка в течение 30 дней после сдачи.
Сроки: новый кластер с нуля — 2-3 дня, аудит и перенастройка существующего production-кластера с минимальным downtime — 4-5 дней. Стоимость рассчитывается индивидуально после аудита инфраструктуры. Оценим ваш проект — получите консультацию. Мы выполнили более 40 проектов по оптимизации Kafka, что подтверждает нашу экспертизу.
Типичные ошибки при настройке кластера
-
min.insync.replicas=1при replication.factor=3 — потеря данных при отказе единственной in-sync реплики. - Отсутствие rack-awareness — все брокеры в одной зоне доступности.
- Слишком много партиций (более 1000 на брокер) — деградация контроллера.
-
unclean.leader.election.enable=true— риск потери сообщений. - Не настроен мониторинг
RequestHandlerAvgIdlePercent— незаметная перегрузка брокеров.







