Насколько я понимаю, и Kafka Producer, и Consumer должны использовать один поток для каждой темы-раздела, если мы хотим писать/читать записи в порядке. Я прав или, может быть, они используют несколько потоков в таких ситуациях?
Таким образом, порядок может быть достигнут в Kafka как в однопоточной, так и в многопоточной среде.
один брокер/один раздел -> потребительская модель на основе одного потока
Порядок сообщений в Kafka хорошо работает для одного раздела. Но с одним разделом трудно добиться параллелизма и балансировки нагрузки. Обратите внимание, что в этом случае для доступа к разделу темы будет использоваться только один поток, поэтому порядок всегда гарантируется.
несколько брокеров / несколько разделов -> Модель потребителей на основе многопоточности (с группами потребителей, содержащими более 1 потребителя)
В этом случае мы предполагаем, что в теме присутствует несколько разделов, и каждый раздел обрабатывается одним потребителем (точнее, одним потоком) в каждой группе потребителей, что справедливо называется многопоточностью.
Есть три метода, с помощью которых мы можем сохранить порядок сообщений внутри разделов в Kafka. Каждый метод имеет свои плюсы и минусы.
Способ 1: Круговая система или распыление
Способ 2: Раздел ключа хеширования
Способ 3: Пользовательский разделитель
Круговой алгоритм или распыление (по умолчанию)
В этом методе разделенный будет отправлять сообщения всем разделам в циклическом режиме, обеспечивая сбалансированную нагрузку на сервер. Перегрузки любого раздела не произойдет. С помощью этого метода достигается параллелизм и балансировка нагрузки, но он не поддерживает общий порядок, но порядок внутри раздела будет поддерживаться. Это метод по умолчанию, и он не подходит для некоторых бизнес-сценариев.
Чтобы преодолеть описанные выше сценарии и сохранить порядок сообщений, давайте попробуем другой подход.
Раздел ключа хеширования
В этом методе мы можем создать ProducerRecord, указав ключ сообщения с каждым сообщением, передаваемым в тему, чтобы обеспечить упорядочение разделов.
Разделение по умолчанию будет использовать хэш ключа, чтобы гарантировать, что все сообщения для одного и того же ключа отправляются в один и тот же раздел. Это самый простой и распространенный подход. Это тот же метод, который использовался и для улья. Он использует операцию по модулю для хеширования.
Хэш (ключ) % Количество разделов -> Номер раздела
Можно сказать, что ключ здесь поможет определить раздел, куда производитель всегда хочет отправлять сообщение, чтобы поддерживать порядок. Но недостатком этого метода является то, что он использует случайное хэш-значение для извлечения данных в назначенный раздел и следует за перегрузкой данных в один раздел. Но недостатком этого метода является то, что он использует случайное хэш-значение для извлечения данных в назначенный раздел и следует за перегрузкой данных в один раздел.
Пользовательский разделитель
Мы можем написать нашу собственную бизнес-логику, чтобы решить, какое сообщение нужно отправить в какой раздел. При таком подходе мы можем упорядочить сообщения в соответствии с нашей бизнес-логикой и одновременно добиться параллелизма.
Для понимания более подробной информации вы можете проверить ниже
Также обратите внимание, что эта информация представляет параллелизм на уровне раздела
Также появилась новая стратегия параллелизма под названием параллелизм на потребительском уровне.. Я не читал ее, но вы можете найти подробности по ссылке ниже.
https://www.confluent.io/blog/introduction-confluent-parallel-message-processing-client/