Перейти к содержанию

Сайзинг топиков Kafka

1. Входные данные

Прежде чем что-то считать, нужно собрать базовую информацию о потоке данных, который пойдет через топик.

  • Средний размер сообщения (Avg. Message Size): Размер одного сообщения в байтах до сжатия. Например, 1 КБ.
  • Пиковая интенсивность записи (Peak Ingestion Rate): Количество сообщений в секунду, которое продюсеры будут отправлять в топик в моменты пиковой нагрузки. Например, 1000 сообщений/сек.
  • Требуемое время хранения данных (Retention Period): Как долго данные должны быть доступны в тестовой среде. Это самый важный параметр для экономии места. Если для прода это могут быть дни или недели, для тестов часто достаточно нескольких часов или одного дня.
  • Коэффициент сжатия (Compression Ratio): Допустим, используется zstd, который является очень эффективным. Для текстовых данных (JSON, логи) он может достигать 5x-10x. Для бинарных данных — меньше, около 2x-3x. Возьмем для расчета средний коэффициент 4x (т.е. данные на диске занимают в 4 раза меньше места).

2. Расчет требуемого дискового пространства на топик

Это главный расчет, который поможет не выйти за пределы HDD.

Формула:

Total_Disk_Space = (Rate_per_Sec * Avg_Msg_Size * Retention_in_Secs / Compression_Ratio) * Replication_Factor

Где:

  • Total_Disk_Space — общее место на дисках всех брокеров для одного топика.
  • Rate_per_Sec — интенсивность записи (сообщений/сек).
  • Avg_Msg_Size — средний размер сообщения (байт).
  • Retention_in_Secs — время хранения в секундах (например, 24 часа = 86400 сек).
  • Compression_Ratio — ваш коэффициент сжатия (например, 4).
  • Replication_Factor — количество реплик данных.

Место на одном брокере:

Disk_Space_per_Broker ≈ Total_Disk_Space / Replication_Factor
Это примерное значение, так как распределение партиций по брокерам может быть неравномерным, но для оценки подходит.


3. Выбор ключевых характеристик топика

Имея методику расчета, можно осознанно выбрать параметры для создания топика.

retention.ms и retention.bytes

Это настройки, которые определяют, как долго хранятся данные. Kafka удалит сегмент, если он стал старше retention.ms ИЛИ если общий размер партиции превысил retention.bytes.

  • Для тестовой среды с ограниченным HDD, retention.ms — ваш главный инструмент.
    • Рекомендация: Установите минимально необходимое время для проведения тестов. Например, если тесты занимают 2 часа, установите retention.ms на 4-6 часов (с запасом). Для суточных тестов — 24-30 часов.
    • Пример: retention.ms=86400000 (24 часа).
  • retention.bytes можно установить в качестве дополнительной защиты, чтобы одна партиция не "раздулась" до бесконечности из-за всплеска трафика. Но основным ограничителем лучше делать время.

replication.factor (Фактор репликации)

Этот параметр определяет, на скольких брокерах будет храниться копия каждой партиции.

  • У вас 3 брокера.
  • replication.factor=3: Максимальная отказоустойчивость. Кластер переживет отказ 2 брокеров (при min.insync.replicas=1). Но это требует в 3 раза больше дискового пространства.
  • replication.factor=2: Хороший компромисс для тестовой среды. Переживет отказ 1 брокера. Требует в 2 раза больше места. Это рекомендуемый вариант для экономии места.
  • replication.factor=1: Нет отказоустойчивости. Если брокер с партицией падает, данные становятся недоступны. Используйте только для маловажных данных, где потеря не страшна.

Рекомендация для вас: Начните с replication.factor=2.

partitions (Количество партиций)

Партиции — это единица параллелизма в Kafka.

  • Правило №1: Количество партиций должно быть >= максимальному количеству консьюмеров в одной consumer group, которые должны работать одновременно. Если будет 4 инстанса сервиса-консьюмера, нужно минимум 4 партиции, чтобы все они работали.
  • Правило №2: Большее количество партиций позволяет лучше распределить нагрузку по брокерам. Для 3 брокеров хорошо подходят числа, кратные 3 (например, 3, 6, 12), чтобы нагрузка распределилась равномерно.
  • Недостатки большого числа партиций: Каждая партиция — это открытые файловые дескрипторы и нагрузка на Zookeeper/контроллер. Для тестовой среды не стоит создавать сотни партиций без необходимости.

Рекомендация для вас: Начните с небольшого числа, например, partitions=3 или partitions=6. Этого хватит для большинства тестов и нагрузка будет равномерно распределена по брокерам.


4. Пример расчета

Давайте посчитаем на конкретных цифрах.

Входные данные:

  • Средний размер сообщения: 2 КБ (2048 байт)
  • Интенсивность записи: 500 сообщ/сек
  • Время хранения: 8 часов (28800 секунд)
  • Коэффициент сжатия zstd: 4x
  • Выбранные параметры топика:
    • replication.factor: 2
    • partitions: 6

Расчет:

  1. Входящий поток данных (до сжатия): 500 сообщ/сек * 2048 байт/сообщ = 1,024,000 байт/сек ≈ 1 МБ/сек

  2. Объем данных за 8 часов (до сжатия): 1 МБ/сек * 28800 сек = 28800 МБ ≈ 28.1 ГБ

  3. Объем данных на диске с учетом сжатия (для одной реплики): 28.1 ГБ / 4 = 7.025 ГБ

  4. Общий объем на кластере с учетом репликации: 7.025 ГБ * 2 (replication.factor) = 14.05 ГБ

Итог: Для одного такого топика вам потребуется около 14 ГБ дискового пространства на всем кластере. Каждый из 3 брокеров будет хранить примерно 14.05 / 3 ≈ 4.7 ГБ данных этого топика (так как 6 партиций с RF=2 будут распределены по 3 брокерам).


5. Дополнительные рекомендации

  • min.insync.replicas: Этот параметр критичен для гарантии доставки. Он определяет, сколько реплик должны подтвердить запись, чтобы она считалась успешной. Устанавливайте его в replication.factor - 1.
    • Если replication.factor=3, то min.insync.replicas=2.
    • Если replication.factor=2, то min.insync.replicas=1. Важно: min.insync.replicas=1 означает, что вы не получите гарантии сохранности данных при падении единственного брокера, который успел записать сообщение. Для тестов это может быть приемлемо.
  • Zookeeper: Одна нода Zookeeper — это единая точка отказа (SPOF). Если она упадет, ваш кластер перестанет работать (нельзя будет создавать топики, новые продюсеры и консьюмеры не смогут подключиться). Для тестовой среды это может быть допустимо, но для прода нужно минимум 3 ноды ZK. Поскольку у вас Kafka v3.6, рассмотрите в будущем переход на KRaft, который избавляет от необходимости в Zookeeper.
  • Размер сегмента (segment.bytes=128 MB): Это хороший, сбалансированный размер. Он означает, что файлы логов будут закрываться и становиться доступными для удаления/сжатия при достижении 128 МБ. Для топиков с низкой интенсивностью записи можно уменьшить это значение (например, до 64 МБ), чтобы политика очистки (retention.ms) срабатывала на более мелких файлах и быстрее освобождала место.

Что дальше?

  1. Нашли эту статью полезной? Поделитесь ею и помогите распространить знания!
  2. Нашли ошибку или есть идеи 💡 о том, что и как я могу улучшить? Напишите мне в Telegram.
  3. Хотите узнать обо мне больше? Читайте здесь.