Можно ли влиять на выбор партиции при отправке сообщения продюсером в Kafka
Что проверяют
Знаете ли вы, как продюсер выбирает партицию по умолчанию и какие рычаги у вас есть, и понимаете ли, что от партиции зависит порядок сообщений. Следом обычно спрашивают, что станет с распределением, если добавить в топик партиции.
Как отвечать
Да, и рычагов несколько, от мягкого к жёсткому:
- ключ сообщения: сообщения с одинаковым
Keyпопадают в одну партицию и читаются по порядку. Это основной и правильный способ, ключом делают идентификатор заказа, клиента, агрегата; - алгоритм партиционирования: в
ProducerConfigесть свойствоPartitioner.Confluent.Kafkaпостроен на librdkafka, и по умолчанию тамConsistentRandom: CRC32 от ключа и случайная партиция для сообщений без ключа. Java-клиент хэширует ключ через murmur2, поэтому при смешанных продюсерах одинаковый ключ из C# и Java уйдёт в разные партиции. ЛечитсяPartitioner = Partitioner.Murmur2Random; - своя логика:
ProducerBuilder.SetPartitioner(topic, ...)илиSetDefaultPartitioner(...)принимает делегат, который получает имя топика, число партиций и байты ключа и возвращаетPartition; - явная партиция:
ProduceAsync(new TopicPartition("orders", new Partition(3)), message). Полный контроль, но балансировка целиком на вас.
Цену тоже стоит назвать. Добавление партиций меняет соответствие ключей и партиций, и порядок для старых ключей на переходе ломается. Перекос ключей создаёт горячую партицию, которую в группе читает один консьюмер.
Где спотыкаются
Пишут партиционер через key.GetHashCode(). В современном .NET хэш строк рандомизирован для каждого процесса, и после перезапуска тот же ключ уходит в другую партицию. К тому же Math.Abs(int.MinValue) бросает OverflowException.
Переносят подход из Java-клиента, где пишут класс, реализующий интерфейс Partitioner, и ищут аналог IPartitioner. В Confluent.Kafka такого интерфейса нет, используется делегат.
Выбирают партицию вручную ради «равномерности». Получают сломанный порядок по ключу и код, который приходится переписывать при каждом изменении числа партиций.