В Apache Kafka почему не может быть больше экземпляров потребителей, чем разделов?

Я узнаю о Кафке, читаю секцию введения здесь

https://kafka.apache.org/documentation.html#introduction

в частности, часть о потребителях. Во втором-последнем абзаце во введении он читает

Кафка делает это лучше. Имея понятие параллелизма - раздел - в рамках тем, Kafka может обеспечить как заказывающие гарантии, так и балансировку нагрузки над пулом потребительских процессов. Это достигается путем назначения разделов в теме для потребителей в группе потребителей, так что каждый раздел потребляется ровно одним потребителем в группе. Делая это, мы гарантируем, что потребитель является единственным читателем этого раздела и потребляет данные по порядку. Поскольку существует много разделов, это все равно уравновешивает нагрузку на многие экземпляры потребителей. Однако обратите внимание, что не может быть больше экземпляров клиентов, чем разделов.

Моя путаница проистекает из этого последнего предложения, потому что в изображении, прямо над тем абзацем, где автор изображает две группы потребителей и тему с четырьмя разделами, есть больше экземпляров потребителей, чем разделы!

Также не имеет смысла, что не может быть больше экземпляров потребителей, чем разделов, потому что тогда разделы были бы невероятно малы, и кажется, что накладные расходы при создании нового раздела для каждого экземпляра потребителя будут болеть Kafka. Я понимаю, что разделы используются для отказоустойчивости и снижения нагрузки на каком-либо одном сервере, но приведенное выше предложение не имеет смысла в контексте распределенной системы, которая, как предполагается, сможет обрабатывать тысячи потребителей за раз.

Ответ 1

Хорошо, чтобы понять это, нужно понять несколько частей.

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

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

Кафка делает это лучше. Имея понятие параллелизма - раздел - в рамках тем, Kafka может обеспечить как заказывающие гарантии, так и балансировку нагрузки над пулом потребительских процессов. Это достигается путем назначения разделов в теме для потребителей в группе потребителей, так что каждый раздел потребляется ровно одним потребителем в группе. Делая это, мы гарантируем, что потребитель является единственным читателем этого раздела и потребляет данные по порядку. Поскольку существует много разделов, это все равно уравновешивает нагрузку на многие экземпляры потребителей. Однако обратите внимание, что не может быть больше экземпляров клиентов, чем разделов.

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

Также, как вы думаете, это ограничение производительности (несколько разделов) - это фактически увеличение производительности, так как Kafka может выполнять действия разных разделов полностью параллельно, ожидая окончания остальных разделов.

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

Вначале описываются два сценария:

Если все экземпляры потребителя имеют одну и ту же группу потребителей, то это работает так же, как традиционная балансировка нагрузки для потребителей.

Если все экземпляры потребителя имеют разные группы потребителей, то это работает как публикация-подписка, и все сообщения передаются всем потребителям.

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

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

Ответ 2

Важно помнить, что Kafka сохраняет одно смещение за [потребительская группа, тема, раздел]. Это причина.

Я предполагаю, что предложение

Однако обратите внимание, что не может быть больше экземпляров клиентов, чем разделов.

относится к режиму "автоматический перерасчет групп потребителей", режим потребления по умолчанию, когда вы просто подписываете() некоторое количество потребителей на список тем.

Я предполагаю, что, поскольку, по крайней мере, с Kafka 0.9.x, ничто не мешает иметь несколько экземпляров клиентов, членов одной группы, читающих один и тот же раздел.

Вы можете сделать что-то подобное в двух или более разных потоках

Properties props = new Properties();
props.put(ConsumerConfig.GROUP_ID_CONFIG, "MyConsumerGroup");
props.put("enable.auto.commit", "false");
consumer = new KafkaConsumer<>(props);
TopicPartition partition0 = new TopicPartition("mytopic", 0);
consumer.assign(Arrays.asList(partition0));
ConsumerRecords<Integer, String> records = consumer.poll(1000);

и у вас будет два (или более) пользователя, читающих один и тот же раздел.

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

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

Если вы хотите, чтобы каждый потребитель читал разные сообщения, вам придется синхронизировать их, так что только один может выбрать и зафиксировать смещение во время.

Ответ 3

Существует причина, по которой Kafka не может поддерживать несколько потребителей на раздел.

Брокер Kafka записывает данные в файл для каждого раздела. Итак, скажем, если настроены два раздела, брокер создаст два файла и назначит несколько групп потребителей, где могут быть отправлены сообщения.

Теперь для каждого раздела только один потребитель потребляет сообщения на основе смещения файла. например, потребитель 1 сначала будет считывать сообщения из смещения файла 0 до 4096. Теперь эти смещения являются частью полезной нагрузки, поэтому потребитель будет знать, какое смещение использовать при запросе на чтение следующих сообщений.

Если несколько пользователей читают один и тот же раздел, то потребитель 1 читает из файла со смещением 0-4096, но потребитель 2 все равно будет пытаться читать со смещения 0, если он также не получает сообщение, отправленное потребителю 1. Теперь, если одни сообщения отправляются нескольким потребителям, чем это не балансировка нагрузки, поэтому Kafka разделил их на группы потребителей, чтобы все группы потребителей могли получать сообщения, но в пределах группы потребителей, только один потребитель может получать сообщение.

Ответ 4

В Kafka только один экземпляр пользователя может потреблять сообщения из раздела. Если экземпляры пользователей больше, чем разделы, то не будет использования дополнительных экземпляров потребителей. Таким образом, кафка не разрешает эти дополнительные потребительские экземпляры.

Теперь, если несколько потребителей могут потреблять раздел, тогда не будет никакого упорядочения в потреблении сообщений. Вот почему кафка не разрешает нескольким потребителям на раздел