Объяснение через QnA

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

У меня было много вопросов, на которые мне нужно было получить ответы, прежде чем приступить к реализации такого дизайна, и я хотел понять, как работает Kafka в таком сценарии.

Давайте рассмотрим некоторые из этих вопросов и ответы, которые я нашел во время своих поисков.

Q1. Разрешено ли в Kafka одной группе потребителей одновременно использовать сообщения из нескольких тем?

А. Да, дизайн Kafka позволяет потребителям из одной потребительской группы получать сообщения из разных тем.

Протокол, лежащий в основе consumer.poll(), позволяет отправлять запросы для нескольких разделов (в том числе по темам) в одном запросе.

Когда вызывается consumer.poll(), FetchRequest объекты отправляются брокерам, на которых размещаются лидеры разделов, и возвращаются все, т. е. max.poll.records, поставленные в очередь сообщения.

consumer.poll() возвращает карту тем с записями для подписанного списка тем и разделов.

Q2. Как подписаться на несколько тем?

A.

consumer.subscribe(Arrays.asList(topic1, topic2))

Да, это просто. Поняв, что потребительский API предоставляет эту возможность, я был уверен, что Kafka должен обрабатывать такой сценарий под капотом, но мне было любопытно узнать больше.

Q3. Как Kafka гарантирует, что темы не будут голодать?

А. Сообщения помещаются в очередь, начиная с первого раздела, если в текущем разделе больше нет сообщений, но есть еще байты для заполнения, сообщения из следующего раздела будут помещены в очередь до тех пор, пока не закончатся сообщения или буфер полный.

После того, как потребитель получит буфер, он разделит его на CompletedFetches, где один CompletedFetch содержит все сообщения одного раздела темы, CompletedFetches ставятся в очередь.

Поставленные в очередь CompletedFetches логически объединяются в одну большую очередь, и, поскольку запросы к каждому разделу отправляются параллельно, они могут смешиваться друг с другом.

consumer.poll() будет считывать и удалять из очереди в most max.poll.records из этой сглаженной большой очереди.

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

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

Q4. Как совершаются смещения?

A. Смещения, совершенные потребителями, хранятся в специальной теме Kafka под названием __consumer_offsets, в которой сохраняются смещения для каждого раздела каждой темы.

Q5. Как обеспечить оптимальную пропускную способность?

A. Чтобы обеспечить оптимальное потребление сообщений из разных тем и избежать больших пакетов сообщений из одной темы за другой, вам может потребоваться обратить внимание на следующие свойства:

  1. Размер сообщения — размер сообщения, получаемого из темы.
  2. fetch.min.bytes — минимальное количество байтов, которое потребитель хочет получить от брокера.
  3. max.partition.fetch.bytes — Максимальное количество байтов, которое будет использовано на один раздел.