Опишите, как Kafka Producer выбирает партицию для отправки сообщения.

Ответ

В Kafka выбор партиции для сообщения управляется компонентом Partitioner. По умолчанию используется DefaultPartitioner, логика работы которого следующая:

  1. Если у сообщения указан ключ (Key):

    • Партиция вычисляется на основе хеша от ключа (используется алгоритм murmur2), который затем берется по модулю от общего количества партиций в топике: hash(key) % numPartitions.
    • Это гарантирует, что все сообщения с одинаковым ключом всегда будут попадать в одну и ту же партицию, что обеспечивает строгий порядок их обработки.
  2. Если ключ у сообщения отсутствует (Key is nil):

    • Сообщения распределяются по партициям поочередно (алгоритм 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)
// ...