MAATRIX / Блог / Как установить и настроить Apache Kafka на VPS

Как установить и настроить Apache Kafka на VPS

MAATRIX

Когда сервисы начинают общаться напрямую через REST и очередь сообщений превращается в узкое место, а логи событий нужно хранить и переигрывать заново — приходит время Kafka. Это не просто «ещё одна очередь»: Kafka пишет поток событий на диск, хранит его сколько нужно и позволяет десяткам потребителей читать один и тот же лог независимо друг от друга. Ниже — рабочая установка на чистый VPS без Zookeeper (начиная с 4-й ветки Kafka он убран совсем, используется встроенный режим KRaft), с systemd-сервисом, настройкой памяти и минимальным мониторингом.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Требования к серверу

Kafka не самая лёгкая система: JVM держит heap, а сама Kafka активно полагается на page cache операционной системы для быстрого чтения-записи сегментов лога. Экономить на диске — плохая идея: под нагрузкой Kafka пишет последовательно, но при большом числе партиций и consumer-групп растут случайные чтения, поэтому SSD/NVMe — не роскошь, а необходимость.

СценарийvCPURAMДиск
Тест / разработка24 ГБ20 ГБ SSD
Небольшая прод-нагрузка, 1 брокер48 ГБ50-100 ГБ NVMe
Прод, несколько брокеров4-8 на брокер16 ГБ на брокер200+ ГБ NVMe, отдельный диск под логи

Для продакшена Kafka принято ставить как минимум 3 брокера с replication factor 3 — иначе падение одного узла означает потерю недоставленных сообщений. В этой статье разворачиваем один брокер: этого достаточно, чтобы понять механику и запустить пилот, а масштабирование до кластера — вопрос повторения тех же шагов на других узлах с разными node.id.

Дальше все команды — для Ubuntu 24.04, пользователь с sudo.

Установка Java и Kafka

Kafka работает на JVM, актуальным версиям нужен Java 17 или новее:

sudo apt update
sudo apt install -y openjdk-21-jre-headless wget gnupg2

java -version

Создаём отдельного системного пользователя — Kafka не должна работать от root:

sudo useradd -r -m -d /opt/kafka -s /bin/false kafka

Точную версию лучше не жёстко прописывать в статье, а брать актуальную с сайта загрузок на момент установки — узнать и скачать можно так:

cd /tmp
KAFKA_VERSION=$(curl -s https://downloads.apache.org/kafka/ \
  | grep -oP '(?<=href=")[0-9]+\.[0-9]+\.[0-9]+(?=/")' | sort -V | tail -1)
echo "Актуальная версия: $KAFKA_VERSION"

wget "https://downloads.apache.org/kafka/${KAFKA_VERSION}/kafka_2.13-${KAFKA_VERSION}.tgz"
sudo tar -xzf "kafka_2.13-${KAFKA_VERSION}.tgz" -C /opt/kafka --strip-components=1
sudo chown -R kafka:kafka /opt/kafka

kafka_2.13 — сборка под Scala 2.13, стандартный выбор для большинства окружений.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Настройка KRaft-режима (без Zookeeper)

Раньше Kafka требовала отдельный кластер Zookeeper для хранения метаданных. С KRaft брокер сам является и хранилищем метаданных, и узлом обработки — меньше движущихся частей, меньше что может сломаться на одиночном VPS.

Открываем конфиг (в версиях 3.x он может лежать в config/kraft/server.properties, в 4.x — это уже единственный config/server.properties, так как режим с Zookeeper удалён):

sudo -u kafka nano /opt/kafka/config/server.properties

Ключевые параметры для одиночного брокера-контроллера:

process.roles=broker,controller
node.id=1
controller.quorum.voters=1@127.0.0.1:9093

listeners=PLAINTEXT://0.0.0.0:9092,CONTROLLER://127.0.0.1:9093
advertised.listeners=PLAINTEXT://YOUR_SERVER_IP:9092
controller.listener.names=CONTROLLER
inter.broker.listener.name=PLAINTEXT

log.dirs=/var/lib/kafka/logs
num.partitions=3
default.replication.factor=1
min.insync.replicas=1

advertised.listeners — критичный параметр: именно этот адрес Kafka отдаёт клиентам при подключении. Если оставить localhost, приложения с других серверов подключатся к брокеру, получат список адресов и упрутся в localhost, который для них никуда не ведёт. Подставьте реальный внешний или внутренний IP сервера.

Создаём каталог под данные и форматируем хранилище — без этого шага брокер откажется стартовать:

sudo mkdir -p /var/lib/kafka/logs
sudo chown -R kafka:kafka /var/lib/kafka

KAFKA_CLUSTER_ID=$(sudo -u kafka /opt/kafka/bin/kafka-storage.sh random-uuid)
sudo -u kafka /opt/kafka/bin/kafka-storage.sh format \
  -t "$KAFKA_CLUSTER_ID" -c /opt/kafka/config/server.properties

UUID кластера генерируется один раз и сохраняется в metadata-лог — сохраните его отдельно, он пригодится при добавлении новых брокеров в кластер.

Автозапуск через systemd

Ручной запуск бинарником удобен для теста, но в проде нужен systemd — с автоперезапуском при падении и нормальными логами через journalctl.

sudo nano /etc/systemd/system/kafka.service
[Unit]
Description=Apache Kafka (KRaft)
After=network.target

[Service]
Type=simple
User=kafka
Group=kafka
Environment="KAFKA_HEAP_OPTS=-Xms1G -Xmx1G"
ExecStart=/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties
ExecStop=/opt/kafka/bin/kafka-server-stop.sh
Restart=on-failure
RestartSec=10
LimitNOFILE=100000

[Install]
WantedBy=multi-user.target

LimitNOFILE поднимаем сразу — Kafka открывает много файловых дескрипторов (по одному на сегмент лога и на соединение), и стандартный лимит в 1024 на боевой нагрузке будет исчерпан.

sudo systemctl daemon-reload
sudo systemctl enable --now kafka
sudo systemctl status kafka

Если сервис не стартует — первым делом смотрите journalctl -u kafka -n 100 --no-pager: чаще всего причина в правах на /var/lib/kafka/logs или в незакрытом порте 9092/9093 другим процессом.

Первый топик и проверка потока

Топик — это именованный поток событий, разбитый на партиции для параллелизма. Создаём тестовый:

/opt/kafka/bin/kafka-topics.sh --create \
  --topic test-events \
  --bootstrap-server localhost:9092 \
  --partitions 3 \
  --replication-factor 1

Проверяем список и детали:

/opt/kafka/bin/kafka-topics.sh --list --bootstrap-server localhost:9092
/opt/kafka/bin/kafka-topics.sh --describe --topic test-events --bootstrap-server localhost:9092

Пишем сообщения консольным продюсером (в одном терминале) и читаем консольным консьюмером (в другом):

# Терминал 1 — отправка
/opt/kafka/bin/kafka-console-producer.sh --topic test-events --bootstrap-server localhost:9092

# Терминал 2 — чтение с самого начала
/opt/kafka/bin/kafka-console-consumer.sh --topic test-events \
  --from-beginning --bootstrap-server localhost:9092

Если сообщения из первого терминала появляются во втором — брокер работает и принимает соединения снаружи процесса. На этом этапе стоит сразу закрыть порт 9092 фаерволом от всего интернета и открыть только для доверенных IP приложений:

sudo ufw allow from 203.0.113.10 to any port 9092 proto tcp
sudo ufw deny 9092

Порт 9093 (контроллер) вообще не должен быть доступен снаружи — в конфиге выше он и так слушает только 127.0.0.1.

Память, ретеншн и производительность

Heap для JVM в примере выше — 1 ГБ, и для большинства нагрузок этого достаточно: Kafka не хранит данные в heap, она пишет их на диск и читает через page cache, а heap нужен в основном под индексы и служебные структуры. Раздувать heap до половины оперативной памяти — частая ошибка: чем больше heap, тем дольше паузы на сборку мусора и тем меньше памяти остаётся операционной системе под page cache, от которого напрямую зависит скорость чтения.

Ориентировочное правило: heap — 25-30% RAM сервера, остальное оставляем системе. Для сервера с 8 ГБ RAM это -Xms2G -Xmx2G, не больше.

Ретеншн — сколько Kafka хранит данные до удаления — настраивается на уровне брокера (по умолчанию для новых топиков) или на уровне конкретного топика:

# в server.properties — дефолт для всех топиков
log.retention.hours=168
log.retention.bytes=-1
log.segment.bytes=1073741824

Для отдельного топика можно переопределить прямо через kafka-configs.sh, например хранить только сутки для высокочастотного потока метрик:

/opt/kafka/bin/kafka-configs.sh --alter \
  --bootstrap-server localhost:9092 \
  --entity-type topics --entity-name test-events \
  --add-config retention.ms=86400000

Число партиций напрямую определяет максимальный параллелизм чтения — партиций не может читать одновременно больше consumer'ов, чем их количество в топике. Начинайте с 3-6 партиций на топик и увеличивайте по мере роста числа потребителей, но учтите: партиции легко добавить, но нельзя уменьшить без пересоздания топика.

Мониторинг и логи

Без метрик Kafka — чёрный ящик: не видно ни lag консьюмеров, ни заполненности дисков под логами. Стандартный путь — JMX Exporter, который отдаёт метрики JVM и Kafka в формате Prometheus:

sudo -u kafka mkdir -p /opt/kafka/jmx-exporter
sudo -u kafka wget -O /opt/kafka/jmx-exporter/jmx_prometheus_javaagent.jar \
  https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/1.0.1/jmx_prometheus_javaagent-1.0.1.jar

Добавляем javaagent в systemd-юнит:

Environment="KAFKA_OPTS=-javaagent:/opt/kafka/jmx-exporter/jmx_prometheus_javaagent.jar=7071:/opt/kafka/jmx-exporter/kafka.yml"

Дальше метрики с порта 7071 забирает Prometheus и визуализирует Grafana — если такой связки на сервере ещё нет, разворачивается она за один заход по инструкции Grafana и Prometheus на VPS. Из метрик в первую очередь стоит вывести на дашборд kafka_server_replicamanager_underreplicatedpartitions (недореплицированные партиции — сигнал проблемы) и consumer lag по группам.

Журнал самого брокера смотрите через journalctl -u kafka -f, а логи данных (не путать с системным логом) физически лежат в /var/lib/kafka/logs — их размер стоит держать под наблюдением так же, как обычный дисковый мониторинг сервера (мониторинг диска на VPS), потому что переполнение диска под сегментами — самая частая причина падения брокера в проде.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Нужен ли Zookeeper в 2026 году?

Нет, для новых установок — не нужен и не должен использоваться. Начиная с Kafka 4.0 режим с Zookeeper удалён из кодовой базы полностью, KRaft — единственный вариант. Если у вас старый кластер на Zookeeper, миграция на KRaft делается через отдельную процедуру kafka-metadata-quorum.sh, описанную в документации конкретной версии, с которой вы мигрируете.

Сколько RAM реально нужно для Kafka на VPS?

Для теста хватает 4 ГБ, для боевой нагрузки с несколькими топиками и активными consumer-группами закладывайте от 8 ГБ на брокер, при этом сама Kafka использует не так много — основной объём съедает page cache операционной системы, и это нормально, не повод паниковать по free -h.

Можно ли развернуть Kafka в Docker вместо установки на голый VPS?

Можно, официальный образ и compose-файлы существуют, и это упрощает обновления. Голая установка через systemd, как в этой статье, обычно даёт чуть предсказуемее производительность диска и проще для одного брокера — если процесс контейнеризации в проекте уже выстроен, посмотрите общий подход в статье про Docker Compose для продакшена на VPS.

Consumer отстаёт от producer — что делать?

Сначала проверьте consumer lag через kafka-consumer-groups.sh --describe --group ваша-группа --bootstrap-server localhost:9092. Если лаг растёт стабильно — либо увеличивайте число партиций и consumer-инстансов в группе (параллелизм упирается именно в партиции), либо ищите узкое место в самой бизнес-логике обработчика, а не в Kafka.

Kafka — это замена Redis или RabbitMQ?

Нет, это разные инструменты. Redis как брокер сообщений — про низкую задержку и простые pub/sub-сценарии без долгого хранения (см. установку Redis на VPS), RabbitMQ — про гибкую маршрутизацию сообщений. Kafka — про устойчивый к сбоям поток событий, который можно переигрывать заново и который выдерживает по-настоящему большой объём при горизонтальном масштабировании партициями.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →