Производитель Kafka - Как изменить топи c без простоя и сохранения порядка сообщений? - PullRequest
2 голосов
/ 28 февраля 2020

Этот вопрос касается миграции тем архитектуры и кафки.

Исходная проблема : эволюция схемы без обратной совместимости.

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.

1 Ответ

1 голос
/ 11 марта 2020

Допустимо ли, чтобы активным был только один производитель?

В этом случае вы можете использовать свою идею с флагом:

  1. Отключить всех производителей p2 , p3, ..., pn за исключением p1
  2. p1 запись только в v1
  3. Переключите флаг на v2, так что p1 заканчивается последняя запись в v1 и запись в v2
  4. Теперь никто не пишет в v1
  5. Запустите других продюсеров p2, p3, ..., pn
  6. Каждый производитель пишет сейчас из-за активного флага на v2, а никто на v1
...