Этот вопрос касается миграции тем архитектуры и кафки.
Исходная проблема : эволюция схемы без обратной совместимости.
https://docs.confluent.io/current/schema-registry/avro.html
Я прошу сообщество дать мне совет или поделиться статьями, из которых я могу получить вдохновение и, возможно, подумать о решении моей проблемы. Может быть, есть архитектура или шаблон потоковой передачи. Нет необходимости указывать решение, определяющее язык c; просто дайте мне направление, в котором я могу go ... У меня большой вопрос, он может быть интересен тем, кто позже хочет
- а) изменить формат сообщения и создать сообщение в новом топи c.
- b) прекратить создавать сообщения в одну топи c и начать создавать сообщения в другую топи c «мгновенно»; другими словами, после создания сообщения в
v2
новые сообщения не добавляются в v1
.
Проблема
Я изменяю формат сообщения, который не совместим с предыдущая версия. Чтобы не сломить существующих потребителей, я решил создать сообщение для новой идеи topi c.
Up-caster
Я читал о повышателе.
https://docs.axoniq.io/reference-guide/operations-guide/production-considerations/versioning-events
Формальное задание
Пусть темы будут v1
и v2
. В настоящее время я создаю сообщения в формате format_v1
в топи c v1
. Я хочу создавать сообщения в формате format_v2
в топи c v2
. Переключение должно произойти в какой-то момент времени, который я могу выбрать.
Другими словами, в какой-то момент все экземпляры производителя прекращают отправлять сообщения в v1
и начинают отправлять сообщения в v2
; таким образом, последнее сообщение m1
в v1
создается перед первым сообщением m2
в v2
.
Подробности
У меня появилась идея, что я могу создавать сообщения для Топи c v1
имеют паровой кафка, который подписан на v1
и переводит преобразованные сообщения в v2
. Предположим, что преобразователь ( в моем случае, конечно, ) способен преобразовывать сообщение format_v1
в format_v2
без ошибок.
Как описано в ссылке выше об эволюции схемы avro к тому времени, когда я добавил up-caster и выдал сообщения в v1
, все мои потребители v1
изменились на v2
.
Теперь сложная часть. У нас есть два требования:
1. Нет простоя производства.
2. Сохранить порядок сообщений.
Это означает:
1) Мы не можем потерять сообщения; клиент может использовать нашу систему в любое время, поэтому наша система должна выдавать сообщение в любое время.
2) Мы работаем с несколькими экземплярами производителя. В некоторый момент времени могут (потенциально) быть производители, которые могут создавать сообщения формата format_v1
в топи c v1
, а некоторые экземпляры, которые создают сообщения формата format_v2
в топи c v2
.
Как мы знаем, kafka не гарантирует порядок сообщений для разных разделов и тем.
Я могу решить проблему с разделами, записав сообщение в v2 с тем же селектором раздела, что и для v1. , Или пока я могу представить, что мы используем только один раздел для v1
и один раздел для v2
.
Мои упрощения и попытки
1) Я представлял, что в тот момент, когда я хочу сменить производителя для создания сообщений в новую топи c, у меня есть повышающий ролик (компонент потока kafka), который способен преобразовывать сообщения из v1
в v2
без ошибок. Этот компонент потока kafka является масштабируемым.
2) Все мои потребители уже включены в v2
topi c. Они постоянно получают сообщения от v2
. В этот момент экземпляры моего производителя выдают сообщения в topi c v1
, и up-caster делает свою работу хорошо.
3) Чтобы упростить проблему, давайте представим, что пока format_v1
и format_v2
не имеют значения, и они одинаковы.
4) Давайте представим, что у нас есть один раздел для v1
и один раздел для v2
.
Теперь моя проблема, как мгновенно переключить всех производителей с данного момента времени; все экземпляры выдают сообщения в топи c v2.
Мой коллега и эксперт по кафке сказал мне, что с простоями это можно сделать
Если вы полагаетесь на заказ из сообщений в разделах вы не можете переключиться на новую версию без простоя. Чтобы свести к минимуму время простоя, мы можем сделать следующее.
Компонент Upcaster должен записать данные в одни и те же разделы и попытаться сделать одинаковые смещения. Однако это не всегда возможно, поскольку смещения могут иметь пропуски, поэтому необходимо сохранять соответствие между старыми смещениями и новыми смещениями. Нет всех записей, только последний объем для каждого раздела. Если сбой upcaster, просто начните снова, производитель все еще не участвует в v2.
Запустите потребителя v2. Если он начинается с той же группы потребителей, что и v1, ничего не следует делать, если у него новая группа потребителей, обновите смещения в Kafka в соответствии с новыми смещениями.
Теперь Producers пишет в v1, upcaster преобразует данные, потребитель использует v2
Здесь наступает время простоя. Когда задержка upcaster близка к 0, завершите работу производителя v1, дождитесь, пока upcaster преобразует остальные записи, завершите работу upcaster, запустите производителя v2, который записывает в v2 topi c.
Хотя я ручных манипуляций в базе данных (через некоторую конечную точку отдыха или др. c) для изменения флага; производители всегда проверяют флаг, прежде чем они производят сообщения. Когда флаг говорит v2
или true
, производитель начнет записывать сообщения в v2
. Однако, что если в момент времени флаг является ложным, один из производителей начинает выдавать сообщение в v1
, тогда флаг меняется, и другой производитель отправляет сообщение в v2
до того, как предыдущий производитель завершил производство в v1
.