Как выбрать количество партиций для топика в Kafka?

Ответ

Количество партиций — это компромисс между параллелизмом и накладными расходами. Это важнейший параметр, который нельзя уменьшить после создания топика.

Критерии выбора:

  1. Максимальный параллелизм потребителей: Один Consumer в группе может читать одну партицию. Для N Consumer'ов нужно минимум N партиций для полной параллельной обработки.
  2. Пропускная способность: Больше партиций позволяет распределить запись и чтение между большим числом брокеров.
  3. Накладные расходы: Каждая партиция — это директория на диске, открытые файлы и память в Zookeeper/Kraft. Слишком большое число (>100 на брокер) снижает производительность.
  4. Распределение по брокерам: Желательно, чтобы число партиций было кратно количеству брокеров для равномерного распределения.

Рекомендации и пример:

  • Low load / тестовые топики: 1-3 партиции.
  • High throughput: Рассчитайте как (макс. число производителей * макс. число потребителей) / число брокеров с запасом.
// Создание топика с 6 партициями и фактором репликации 2
Properties props = new Properties();
props.put("bootstrap.servers", "broker1:9092,broker2:9092");

try (AdminClient admin = AdminClient.create(props)) {
    NewTopic newTopic = new NewTopic("orders", 6, (short) 2);
    admin.createTopics(Collections.singleton(newTopic));
}

Важно: Планируйте с запасом на рост, но избегайте чрезмерного завышения.

Ответ 18+ 🔞

А, слушай, вот эта тема с партициями — это вообще пиздец какой-то фундаментальный выбор, как жениться. Выбрал — и всё, назад не откатишь, блядь. Нельзя просто так взять и уменьшить их количество у живого топика. Пиздец, да?

Так что думать надо с самого начала, а не как обычно — «ой, и так сойдёт». Это компромисс, ёпта, между тем, как быстро мы можем жрать данные, и тем, какой овердохуища накладных расходов мы готовы терпеть.

На что смотрим, когда выбираем это магическое число:

  1. Чтобы все потребители были при деле. Это самое главное, блядь. Один чувак-потребитель (Consumer) в одной группе может читать строго одну партицию. Хочешь, чтобы 10 потребителей работали одновременно? Давай им минимум 10 партиций, иначе кто-то будет сидеть без дела, как лох. Меньше партиций, чем потребителей — и часть из них просто будет сосать лапу, вот и вся магия.
  2. Пропускная способность, ёбана. Больше партиций — значит, запись и чтение можно раскидать по большему количеству брокеров. Это как больше касс в магазине: очередь двигается быстрее.
  3. А вот и подводный ебучий камень — накладные расходы. Каждая партиция — это не просто циферка в конфиге. Это отдельная папка на диске, куча открытых файлов, записей в Zookeeper или в этом новом Kraft. Сделаешь их, например, 10 тысяч на брокер — и он просто накроется медным тазом, будет только успевать метаданные синхронизировать, а не данные передавать.
  4. Равномерность — наше всё. Хорошо бы, чтобы число партиций делилось на количество брокеров. Тогда распределение будет красивым и ровным, без перекосов. Иначе один брокер будет ебашить как проклятый, а другие — в ус дуть.

Ну и примерные ориентиры, чтобы не тыкать пальцем в небо:

  • Для какой-нибудь хуйни, тестов или маленькой нагрузки: 1-3 партиции. Хуй с ним.
  • Для серьёзного пайплайна, где всё летит: Считай. Грубая формула — (макс. число продюсеров * макс. число потребителей) / число брокеров. И сверху накинь запас, процентов 20-30, на всякий пожарный. Вдруг нагрузка вырастет, а мы уже упёрлись в потолок.

Вот, смотри, как это в коде выглядит, тут всё просто:

// Создаём топик "orders" на 6 партиций, и каждая будет в двух копиях (репликация 2)
Properties props = new Properties();
props.put("bootstrap.servers", "broker1:9092,broker2:9092");

try (AdminClient admin = AdminClient.create(props)) {
    NewTopic newTopic = new NewTopic("orders", 6, (short) 2);
    admin.createTopics(Collections.singleton(newTopic));
}

И главный вывод, который бьёт по башке: планируй с запасом, но без фанатизма. Предусмотри рост, но не накидывай партиций просто так, от балды, а то потом будешь сидеть и ебать костыли, разгребая проблемы с производительностью.