Введение
Один заказ могут описывать несколько событий: создание, оплата и отправка. Если связанные записи направляются согласованно, потребитель может проследить последовательность событий этого заказа внутри одного раздела. Ключ записи служит стабильным входным значением для маршрутизации; он отличается от event_id, который обозначает отдельное событие.
Вы опубликуете чередующиеся события трёх заказов в топике с тремя разделами, выведете их фактические ключи и позиции, а затем добавите ещё одно событие существующего заказа. Смещение — это позиция записи внутри одного раздела. Смещения не являются сквозными номерами строк топика, а для записей из разных разделов не гарантируется единый общий порядок.
Брокер и входные учебные данные не зависят от предыдущих работ. Достаточно базовых навыков работы в терминале. Значения событий представлены читаемым текстом JSON; программирование на Python, работа с JSON в программах, настройка кластера и состояние топиков из предыдущих работ не требуются. Не меняйте число разделов и стратегию маршрутизации клиента на протяжении эксперимента. Используйте Terminal.
Опубликуйте чередующиеся события с ключом заказа
На этом шаге вы отправите стабильный идентификатор заказа в качестве ключа, сохранив полное событие в значении. Просмотрите предоставленный пакет из пяти записей:
cd /home/labex/project
cat /home/labex/project/data/keyed-orders.txt
Каждая строка имеет вид key|value. Ключ — это идентификатор заказа. Значение JSON содержит именованные поля в фигурных скобках: event_id уникален, order_id совпадает с ключом, sequence задаёт последовательность бизнес-событий этого заказа, а event_type описывает произошедшее. Текст JSON — это формат значения; Kafka не интерпретирует его автоматически как схему таблицы.
Создайте топик с тремя разделами и одной репликой:
kafka-topics.sh --bootstrap-server localhost:9092 --create --topic orders-keyed --partitions 3 --replication-factor 1
Параметры производителя --reader-property определяют, как он интерпретирует входные строки. parse.key=true и key.separator=| разделяют каждую входную строку по разделителю. Сам разделитель не становится частью ключа или значения. Оператор оболочки < передаёт файл на стандартный ввод, а производитель завершается после отправки всех данных из этого конечного источника:
kafka-console-producer.sh --bootstrap-server localhost:9092 --topic orders-keyed --reader-property parse.key=true --reader-property 'key.separator=|' < /home/labex/project/data/keyed-orders.txt
В файле заказы чередуются, поэтому события order-2001 не расположены рядом во входных данных. При одной и той же стратегии маршрутизации по ключу и неизменном числе разделов одинаковые ключи направляются в один раздел. Разные ключи могут попадать в общий раздел; три заказа не гарантируют три разных номера разделов.
Опубликуйте предоставленный пакет из пяти записей только один раз. Повторное чтение потребителем служит для просмотра; повторный запуск этой команды производителя добавит ещё пять записей. Если вы продолжаете работу после публикации, переходите к просмотру потребителем вместо повторной отправки файла.
Вы задали входное значение для маршрутизации, а не выбрали номер раздела вручную. Далее вы прочитаете фактические результаты маршрутизации вместо попытки угадать их.
Рассмотрите ключи, разделы и смещения вместе
На этом шаге вы выведете метаданные записи вместе с каждым значением. Параметры консольного потребителя --formatter-property управляют отображением, добавляя ключ, раздел и смещение в стандартный вывод. Они не меняют содержимое сохранённых событий. Параметр чтения с начала для нового потребителя, ограничение в пять сообщений и тайм-аут бездействия позволяют повторять этот ограниченный просмотр. Сохраните вывод локально:
kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic orders-keyed --from-beginning --max-messages 5 --timeout-ms 30000 --formatter-property print.key=true --formatter-property print.partition=true --formatter-property print.offset=true > /home/labex/project/output/keyed-first.txt
cat /home/labex/project/output/keyed-first.txt
Каждая строка данных должна содержать поля примерно следующего вида с фактическими числами и полным значением JSON:
Partition:... Offset:... order-... {"event_id":"...",...}
Поля разделены символами табуляции. Найдите k1 и k3: у обоих ключ order-2001, и они должны находиться в одном разделе, причём смещение k3 должно быть больше. Аналогично, k2 и k4 должны находиться в одном разделе для order-2002. Не требуйте, чтобы эти два заказа использовали разные разделы.
Смещения относятся к разделу, а не к ключу. Если в этом разделе есть другие ключи, между смещениями последовательных событий одного заказа могут быть пропуски. Поле sequence в полезной нагрузке — это значение приложения; Kafka не создавала его в качестве смещения.
Потребитель может чередовать записи из разных разделов, поэтому общий порядок вывода не обязан совпадать с файлом производителя. Проверяйте связанные события по ключу, разделу и возрастающим смещениям, а не рассматривайте вывод как один глобально упорядоченный список.
Добавьте ещё одно событие существующего заказа
На этом шаге вы проверите то же правило маршрутизации при ещё одном запуске производителя. Предположите результат для события отправки заказа order-2001: оно должно попасть в существующий раздел этого заказа после его предыдущих записей. Точное смещение зависит от других записей, находящихся в том же разделе.
Шаблон printf из первой работы Kafka передаёт одну полную строку с ключом консольному производителю с теми же настройками:
printf '%s\n' 'order-2001|{"event_id":"k6","order_id":"order-2001","sequence":3,"event_type":"shipped"}' | kafka-console-producer.sh --bootstrap-server localhost:9092 --topic orders-keyed --reader-property parse.key=true --reader-property 'key.separator=|'
Прочитайте все шесть сохранённых записей и сохраните новый результат:
kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic orders-keyed --from-beginning --max-messages 6 --timeout-ms 30000 --formatter-property print.key=true --formatter-property print.partition=true --formatter-property print.offset=true > /home/labex/project/output/keyed-with-shipped.txt
cat /home/labex/project/output/keyed-with-shipped.txt
Найдите k6 с order-2001 и sequence 3. Сравните его раздел с разделом k1 и k3, а смещение — с их смещениями. При просмотре по смещениям внутри раздела последовательность событий заказа должна оставаться created, paid, shipped. Конкретный номер раздела не требуется.
Исходный результат просмотра пяти записей остаётся в keyed-first.txt. Новый производитель добавил событие, а не заменил предыдущие. Число разделов топика и стратегия маршрутизации могут влиять на распределение, поэтому в этом эксперименте они намеренно не меняются. Последующие клиенты должны выбирать совместимую стратегию маршрутизации, если им нужно одинаковое распределение в разных реализациях.
Теперь у вас есть подтверждение стабильной маршрутизации по ключу и порядка внутри раздела без предположений об общем порядке событий или отдельном разделе для каждого заказа. В следующем задании вы примените те же навыки работы с топиками, сроками хранения и публикацией записей с ключами к новому пакету.
Итоги
Вы задали ключи заказов, изучили фактические разделы и смещения и убедились, что добавленное событие следует за предыдущими записями своего заказа при том же правиле маршрутизации. Вы научились различать идентификаторы событий, ключи заказов, последовательность в полезной нагрузке и смещения разделов, не предполагая общего порядка. Далее задание с новым пакетом объединит эти навыки с настройкой срока хранения топика.



