Sobes.tech
Back to questions
Senior
3

Архитектура Apache Kafka: основные компоненты, как продюсеры и консюмеры связаны между собой? Что такое ребалансировка? Как обеспечить последовательное чтение сообщений?

Companies where asked
plata

Answer from AI

sobes.tech AI

Apache Kafka — это распределённая платформа потоковой передачи данных, построенная на основе следующих основных компонентов:

  • Producer (Продюсер) — приложение, которое публикует (отправляет) сообщения в топики Kafka.
  • Consumer (Консюмер) — приложение, которое читает сообщения из топиков.
  • Topic (Топик) — логическая категория или канал, куда продюсеры отправляют сообщения.
  • Partition (Раздел) — топик разбивается на несколько партиций для масштабируемости и параллельной обработки.
  • Broker (Брокер) — сервер Kafka, который хранит данные и обслуживает запросы продюсеров и консюмеров.
  • Consumer Group (Группа консюмеров) — набор консюмеров, которые совместно читают данные из топика, распределяя партиции между собой.

Связь продюсеров и консюмеров происходит через топики и партиции. Продюсер отправляет сообщения в определённый топик, а консюмеры, входящие в группу, получают сообщения из партиций этого топика. Каждая партиция доставляется только одному консюмеру в группе, что обеспечивает параллельную обработку без дублирования.

Ребалансировка (Rebalance) — процесс перераспределения партиций между консюмерами внутри группы. Это происходит, когда консюмеры присоединяются к группе, покидают её или когда меняется количество партиций. Ребалансировка гарантирует, что каждая партиция назначена ровно одному консюмеру.

Для обеспечения последовательного чтения сообщений необходимо:

  • Гарантировать, что сообщения из одной партиции читаются одним консюмером последовательно.
  • Использовать ключи сообщений при отправке, чтобы все сообщения с одним ключом попадали в одну партицию (partitioning by key).
  • Обрабатывать сообщения в консюмере синхронно или с контролем порядка.

Пример на Go с использованием библиотеки sarama (упрощённо):

consumer, err := sarama.NewConsumerGroup(brokers, groupID, config)
// В обработчике ConsumerGroupHandler реализуется метод ConsumeClaim, где читаются сообщения из партиций последовательно
func (h *consumerGroupHandler) ConsumeClaim(sess sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {
    for msg := range claim.Messages() {
        fmt.Printf("Message topic:%s partition:%d offset:%d key:%s value:%s\n", msg.Topic, msg.Partition, msg.Offset, string(msg.Key), string(msg.Value))
        sess.MarkMessage(msg, "")
    }
    return nil
}

Таким образом, последовательность гарантируется в пределах партиции, а ключи помогают направлять связанные сообщения в одну партицию.