Существует ли передовая практика разработки микросервисов для управления версиями таблицы базы данных?

Реализуется система с использованием микросервисов. Чтобы уменьшить количество взаимодействий между микрослужбами, реализованными «на одном уровне» в архитектуре, некоторые микрослужбы будут локально кэшировать копии таблиц, управляемых другими службами. Предполагается, что локально кэшированная таблица (а) часто используется микрослужбой в «режиме чтения» и (б) имеет относительно статическое содержимое (т. е. скорее «таблицу поиска», чем транзакционное содержимое).

Локальные кэши будут поддерживать синхронизацию с помощью обмена сообщениями между службами. Поскольку контент должен быть довольно статичным, это не должно быть серьезной проблемой/рабочей нагрузкой. Однако при запуске микрослужбы существует вероятность того, что локальный кеш устарел.

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

Есть ли «лучшая практика» для этого подхода? Или «лучшая альтернатива», учитывая, что каждый микросервис поддерживается собственной базой данных (т. е. без общей базы данных)?


person SoCal    schedule 01.05.2019    source источник


Ответы (2)


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

Шаблон кэширования

Как правило, в архитектуре микросервисов вы рассматриваете «шаблон кэширования». Вы не строите кеш спереди, а по требованию. Когда вы получаете запрос, вы проверяете кеш, если его там нет, вы обновляете кеш последним значением и возвращаете ответ, оттуда он всегда возвращается из кеша. Преимущество в том, что вам не нужно загружать все спереди. Допустим, у вас есть 200 записей, а службы часто используют только 50 из них, вы поддерживаете дополнительный кеш, который может не потребоваться.

Пусть запросы создают кеш, это однократное попадание в БД. Вы можете установить срок действия кеша, а входящий запрос снова создать его.

Если у вас есть данные, которые полностью статичны (никогда не меняются), то этот шаблон, возможно, не стоит обсуждения, но если у вас есть таблица поиска, которая может меняться даже раз в неделю, месяц, вам следует использовать этот шаблон с более длинным кешем. Время истечения. Поддержание версии может быть дорогостоящим. Но на самом деле вам решать, как вы можете реализовать.

https://docs.microsoft.com/en-us/azure/architecture/patterns/cache-aside

person Imran Arshad    schedule 01.05.2019
comment
Я не считаю кэширование полезным для этого, поскольку нет никакой гарантии, что локально кэшированная строка будет синхронизирована с источником. Кроме того, локальный кеш необходим для удовлетворения ссылок из других таблиц, таблиц, локальных для микрослужбы и управляемых ею. Таким образом, все строки в локальном кеше требуются микрослужбе при запуске (т. е. содержимое локального кеша не управляется запросами к микрослужбе). Но, спасибо, что указали на шаблон без кеша. Это было интересное чтиво. - person SoCal; 02.05.2019

Мы столкнулись с той же проблемой и временно решили ее, используя сравнение временных меток LastUpdated (та же концепция, что и ваш VersionNumber). Каждую ночь (когда наше приложение работает медленно) каждый сервис публикует сообщение ServiceXLastUpdated, которое включает самую последнюю временную метку, когда данные, которыми он владеет, были добавлены/отредактированы. Любая другая служба, которая подписывается на эти данные, обрабатывает сообщение и, если есть несоответствие, запрашивает все строки, «затронутые» с момента последнего локального обновления, чтобы восстановить синхронизацию.

Для нас пока это нормально, так как новые сервисы обычно не появляются в сети и не используются в тот же день. Но наш план на будущее заключается в том, что каждый раз, когда служба запускается, она может публиковать сообщение для каждой подписанной службы, указывающее отметку времени последнего обновления кэша. Если «исходная» служба видит, что метка времени не актуальна, она может отправить обновления для повторной синхронизации данных. Преимущество этого заключается в том, что необходимые обновления отправляются только тем службам, которые в них нуждаются, хотя (по крайней мере, для нас) все службы, на которые подписаны, имеют доступ к сообщениям.

Мы начали с использования постоянных очередей, поэтому, если все экземпляры микросервиса не работают, сообщения просто накапливаются в его очереди. Есть 2 проблемы с этим, которые заставили нас построить что-то лучше:

1) Очевидно, что это не решает сценарий «первого запуска», поскольку в нем нет очереди для сообщений.

2) Если ЧТО-НИБУДЬ пойдет не так при хранении сообщений в очереди или их обработке, вы в конечном итоге потеряете синхронизацию. Если это произойдет, вам по-прежнему нужен упреждающий механизм, как у нас сейчас, чтобы восстановить синхронизацию. Итак, казалось, стоит пойти по этому пути

Я бы не сказал, что наш метод является «лучшей практикой», а если и существует, то я о нем не знаю. Но то, как мы это делаем (включая запланированную будущую работу), до сих пор оказывалось простым в создании, легком для понимания и мониторинге, а также надежным в том смысле, что крайне редко мы получаем событие, вызванное несинхронизированными локальными данными.

person Mikah Barnett    schedule 03.05.2019
comment
Мне нравится идея сравнения на основе временных меток, так как это открывает потенциал (как вы указали) для минимизации количества строк, необходимых для повторной синхронизации таблиц. В настоящее время я склоняюсь к тому, чтобы подписчики запрашивали текущую версию при запуске, но отправка провайдером сообщения при запуске также не кажется плохой идеей (т. Е. Делать и то, и другое). - person SoCal; 05.05.2019
comment
Любопытно... как вы справляетесь с удалением? - person SoCal; 06.05.2019
comment
@SoCal Мы используем флаг в записи, чтобы указать ее статус. Таким образом, удаление — это, по сути, просто модификация строки. РЕДАКТИРОВАТЬ, чтобы добавить: Принимающая служба должна решать, как она обрабатывает удаление, и нет причин, по которым она не может фактически удалить строку (строки) при изменении этого флага. Но на самом деле мы не удаляем их ни в одном текущем варианте использования. - person Mikah Barnett; 06.05.2019