Как установить и настроить Apache Kafka на VPS
Когда сервисы начинают общаться напрямую через REST и очередь сообщений превращается в узкое место, а логи событий нужно хранить и переигрывать заново — приходит время Kafka. Это не просто «ещё одна очередь»: Kafka пишет поток событий на диск, хранит его сколько нужно и позволяет десяткам потребителей читать один и тот же лог независимо друг от друга. Ниже — рабочая установка на чистый VPS без Zookeeper (начиная с 4-й ветки Kafka он убран совсем, используется встроенный режим KRaft), с systemd-сервисом, настройкой памяти и минимальным мониторингом.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Требования к серверу
Kafka не самая лёгкая система: JVM держит heap, а сама Kafka активно полагается на page cache операционной системы для быстрого чтения-записи сегментов лога. Экономить на диске — плохая идея: под нагрузкой Kafka пишет последовательно, но при большом числе партиций и consumer-групп растут случайные чтения, поэтому SSD/NVMe — не роскошь, а необходимость.
| Сценарий | vCPU | RAM | Диск |
|---|---|---|---|
| Тест / разработка | 2 | 4 ГБ | 20 ГБ SSD |
| Небольшая прод-нагрузка, 1 брокер | 4 | 8 ГБ | 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 ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →