Недавно знакомому аналитику задали такой вопрос на собесе:
Как определить, сколько партиций нужно для топика в Кафке?
На мой взгляд это довольно непростой вопрос.
Короткий ответ: это зависит от нефункциональных требований и скорости обработки сообщений.
Давайте разбираться.
Партиция в Кафке — это единица параллелизма. Если мы говорим про обычные консьюмер-группы, то одну партицию в конкретный момент времени может читать только один консьюмер в группе. То есть если у топика 6 партиций, то параллельно читать смогут 6 консьюмеров из одной группы. Седьмой уже будет простаивать.
Аналогия из реальной жизни. Топик — это магазин, партиции — кассы в магазине. Если в магазине всего 6 касс, то даже если на работе 7 кассиров-консьюмеров, работать за кассами смогут только 6 из них. Седьмой будет ждать, кого бы подменить.
При этом один кассир может работать сразу на 6 кассах (если это кассы самообслуживания). И один консьюмер может читать из нескольких партиций.
Чтобы рассчитать число
➡️ Оценить характеристики потока сообщений, который мы обрабатываем:
🧮Сколько событий создается в день/час/секунду?
🧮Какие бывают пики?
Например, в норме 10 000 заказов в день, но в дни распродаж может быть x10.
🧮Сколько длится пик?
🧮Какая задержка обработки допустима?
🧮Какой рост нагрузки ожидается через год?
🧮Нужен ли порядок обработки и в разрезе какого поля?
Например, важно соблюсти порядок действий с заказом: создан, изменен и др. Тогда ключом сообщения можно взять orderId: по нему будет определяться партиция. Все события по заказу с одним orderId попадут в одну партицию (пока мы не меняем количество партиций), а внутри партиции Кафка сохраняет порядок сообщений.
🧮Сколько у нас брокеров в кластере?
➡️ Оценить скорость записи сообщений продюсером и скорость обработки сообщений консьюмером.
Их можно определить на нагрузочном тестировании и затем по результатам уже рассчитывать количество партиций.
➡️ Сделать расчет по формуле из доки Confluent:
разделить объем потока на скорость записи продюсера и скорость обработки консюмера и выбрать максимум.
Например:
- поток 2 000 сообщений в секунду, явных пиков нет
- бизнес ожидает рост в 2 раза -> 4 000 сообщений в секунду
Допустим, нагрузочным тестом выяснили:
- продюсер пишет 1000 сообщений в секунду в одну партицию,
- консьюмер может обрабатывать 250 сообщений в секунду
- в кластере 3 брокера
Чтобы продюсер успевал писать весь объем нужно:
4000 / 1000 = 4 партиции
Чтобы конcьюмеры все успевали обрабатывать без задержек нужно:
4000 / 250 = 16 партиций.
Выбираем максимум из 4 и 16 -> 16.
Удобно брать число, которое хорошо раскладывается по брокерам в кластере и дает запас: 16 -> 18 или 24 партиции. Я бы взяла 24.
Почему с запасом: обработка в консьюмере может затормозить из-за БД, каких-то сетевых задержек.
В идеале объем сообщений оценить не только в сообщениях в секунду, но и в байтах в секунду.
В best practices от Confluent рекомендуется не уходить в экстремальные значения количества партиций, потому что это увеличивает нагрузку на кластер: больше работы для контроллера, дольше ребаланс и восстановление после сбоев. Если по расчету с запасом получилось 24, не надо делать 1000 партиций с мыслями "вдруг пригодится".
➡️ Кафка хороша для сглаживания пиков. Например, у нас случаются кратковременные пики (spike), от которых в топике копятся сообщения, а потом консьюмеры их разбирают. Зная объемы пиковой нагрузки, скорость обработки консьюмера и время, за которое надо разгрести сообщения после пика, можно посчитать, успеют ли консьюмеры это сделать или нужно заложить больше партиций под пики. Тогда в моменты пиковой нагрузки можно увеличивать количество консьюмеров, чтобы они успевали разгребать, а когда нагрузка будет возвращаться к обычному уровню, оставлять меньшее количество консьюмеров, чтобы каждый брал на себя несколько партиций.
Мне кажется, что это вопрос уже уровня архитектора. Или норм для системного аналитика/разработчика, как вы считаете? Что вас обычно спрашивали про Кафку на собесах?
