Микросервисы и присоединения к базам данных

112

Для людей, которые разбивают монолитные приложения на микросервисы, как вы справляетесь с проблемой разделения базы данных? Типичные приложения, над которыми я работал, часто интегрируются с базами данных по причинам производительности и простоты.

Если у вас есть две логически разные таблицы (ограниченные контексты, если хотите), но вы часто выполняете агрегированную обработку больших объемов этих данных, тогда в монолите вы, скорее всего, откажетесь от объектной ориентации и вместо этого будете использовать стандарт своей базы данных. Функция JOIN для обработки данных в базе данных перед возвратом агрегированного представления обратно на уровень приложения.

Как вы оправдываете разделение таких данных на микросервисы, где, предположительно, от вас потребуется «присоединить» данные через API, а не в базе данных.

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

Это кажется немного бойким? Что переживают люди? Какие методы вы использовали для обеспечения приемлемой работы API-соединений?

Мартин Бейли
источник
2
Хороший вопрос, у меня та же проблема, и в итоге я получил материализованное представление и присоединился к нему. Мне это не нравится, но я думаю, что это будет проблемой с Micro Services. Нет правильного способа сделать это, это просто выбор дизайна. Я знаю, что многие люди говорят, что мы можем иметь материализованное представление, но агрегированные ответы становятся проблемой. Дай мне знать, если найдешь что-нибудь получше.
PavanSandeep
Я знаю, что это устарело, но решает ли это graphql? Я также рассматриваю это для сегментированной миграции, и кажется, что graphql - это способ сделать это бесшовным.
themightybun
В какой-то момент вы должны понять, что быть догматиком - это не выход. GraphQL - хороший пример агрегации вне источника данных, и обычно он работает нормально.
Christian Ivicevic

Ответы:

26
  • Когда производительность или задержка не имеют большого значения (да, они нам не всегда нужны), вполне нормально просто использовать простые API RESTful для запроса дополнительных данных, которые вам нужны. Если вам нужно выполнить несколько вызовов разных микросервисов и вернуть один результат, вы можете использовать шаблон шлюза API .

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

  • Кроме того, не забывайте о кешировании :) Вы можете использовать такие инструменты, как Redis или Memcached, чтобы не запрашивать слишком часто другие базы данных.

sap1ens
источник
25
Все хорошие предложения, но мне все еще трудно их рационализировать. Может быть, это потому, что мы так привыкли выполнять много операций с базой данных. В нашем текущем приложении есть сложные хранимые процедуры, которые обрабатывают большие объемы данных, а затем возвращают небольшой набор результатов. В архитектуре микросервисов я бы подумал, что эти сущности должны быть разделены на разные ограниченные контексты. Мы знаем, что нынешний подход уродлив, но трудно оправдать возвращение всех данных на уровень приложения для их обработки. Может быть, поможет дополнительная денормализация или предварительное вычисление агрегированных представлений.
Мартин Бейли
1
О да, я понял. Подход с использованием микросервисов подходит не всем, и вы должны применять его осторожно. Возможно, вы можете начать с небольших изменений.
sap1ens
Возможно, программисты StackExchange были бы лучшим местом, чтобы задать этот вопрос: programmers.stackexchange.com/questions/279409/… и другие вопросы с пометкой microservices programmers.stackexchange.com/questions/tagged/microservices
Мартин Бейли
9

Для сервисов нормально иметь реплицированные копии определенных справочных данных из других сервисов только для чтения.

Учитывая это, при попытке реорганизации монолитной базы данных в микросервисы (в отличие от перезаписи) я бы

  • создать схему БД для службы
  • создавать версионные * представления ** в этой схеме, чтобы предоставлять данные из этой схемы другим службам
  • присоединяется к этим представлениям только для чтения

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

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

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

* просмотры могут быть расширены. Если требуется критическое изменение, создайте v2 того же представления и удалите старую версию, когда она больше не требуется. ** или функции с табличным значением, или Sprocs.

mcintyre321
источник
5

CQRS --- шаблон агрегирования командных запросов - это ответ на этот вопрос согласно Крису Ричардсону. Пусть каждая микрослужба обновляет свою собственную модель данных и генерирует события, которые обновят материализованное представление, имеющее требуемые данные соединения из более ранних микросервисов. Этим MV может быть любая база данных NoSql, Redis или elasticsearch, оптимизированный для запросов. Эти методы приводят к конечной согласованности, что определенно неплохо, и позволяет избежать соединения сторон приложения в реальном времени. Надеюсь, что это ответ.

Praful
источник
2

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

Для микросервисов, которые работают для предоставления данных для отдельных форм, которым нужны данные из других микросервисов (это рабочий случай), я думаю, что использование соединений API - это лучший способ. Вы не пойдете на большие объемы данных, вы можете сделать интеграцию данных в сервисе.

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

Jaro64
источник
1

В Microservices вы создаете diff. прочитайте модели, например, если у вас есть два diff. ограниченный контекст, и кто-то хочет искать по обоим данным, тогда кому-то нужно прослушивать события из ограниченного контекста и создавать представление, специфичное для приложения.

В этом случае потребуется больше места, но соединения не понадобятся.

техаграммер
источник