Ответ
В Kafka выбор партиции для сообщения управляется компонентом Partitioner. По умолчанию используется DefaultPartitioner
, логика работы которого следующая:
Если у сообщения указан ключ (
Key
):- Партиция вычисляется на основе хеша от ключа (используется алгоритм
murmur2
), который затем берется по модулю от общего количества партиций в топике:hash(key) % numPartitions
. - Это гарантирует, что все сообщения с одинаковым ключом всегда будут попадать в одну и ту же партицию, что обеспечивает строгий порядок их обработки.
- Партиция вычисляется на основе хеша от ключа (используется алгоритм
Если ключ у сообщения отсутствует (
Key
isnil
):- Сообщения распределяются по партициям поочередно (алгоритм Round-Robin). Это делается для равномерного распределения нагрузки между партициями.
Кастомная логика
Можно реализовать собственную логику партиционирования, создав кастомный Partitioner
. Для этого в Go (используя популярную библиотеку sarama
) нужно реализовать интерфейс Partitioner
:
// Интерфейс кастомного партиционера
type Partitioner interface {
// Принимает сообщение и общее число партиций,
// возвращает номер партиции и ошибку.
Partition(message *ProducerMessage, numPartitions int32) (int32, error)
RequiresConsistency() bool
}
И затем указать его в конфигурации продюсера:
config := sarama.NewConfig()
// sarama.NewRandomPartitioner - отправляет в случайную партицию
// sarama.NewRoundRobinPartitioner - аналог поведения по умолчанию для сообщений без ключа
// Можно подставить свой собственный: config.Producer.Partitioner = NewMyCustomPartitioner
config.Producer.Partitioner = sarama.NewRandomPartitioner
producer, err := sarama.NewSyncProducer(brokers, config)
// ...