Не существует четкого решения, потому что это полностью зависит от вашего контекста - в частности, от того, в каких измерениях предполагается масштабировать вашу систему и каковы ваши реальные проблемы. Является ли база данных вашим узким местом?
Этот (к сожалению, довольно длинный) ответ будет звучать примерно так: «Микросервисы плохие, монолиты на всю жизнь!», Но это не мое намерение. Я хочу сказать, что микросервисы и распределенные базы данных могут решать различные проблемы, но не без собственных проблем. Чтобы привести веские аргументы в пользу вашей архитектуры, вы должны показать, что эти проблемы не применимы, могут быть смягчены и что эта архитектура является лучшим выбором для нужд вашего бизнеса.
Распространять данные сложно.
Та же самая гибкость, которая обеспечивает лучшее масштабирование, является оборотной стороной более слабых гарантий. Примечательно, что о распределенных системах гораздо сложнее рассуждать.
Атомарные обновления, транзакции, непротиворечивость / ссылочная целостность и долговечность чрезвычайно ценны, и от них не следует отказываться от поспешных решений. Нет смысла иметь данные, если они неполные, устарели или прямо неверны. Если у вас есть ACID в качестве бизнес-требования, но вы используете технологию баз данных, которая не может предложить его «из коробки» (например, многие базы данных NoSQL или архитектура DB-per-microservice), тогда ваше приложение должно заполнить пробел и предоставить эти гарантии.
Это не невозможно сделать, но сложно получить права. Очень сложно. Особенно в распределенной среде, где есть несколько авторов для каждой базы данных. Эта трудность приводит к высокой вероятности ошибок, включая, например, пропущенные данные, противоречивые данные и так далее.
Например, рассмотрите возможность анализа Jepsen хорошо известных систем распределенных баз данных , возможно, начиная с анализа Cassandra . Я не понимаю половину этого анализа, но TL; DR состоит в том, что распределенные системы настолько сложны, что даже ведущие отраслевые проекты иногда ошибаются, и это может показаться очевидным задним числом.
Распределенные системы также подразумевают большие усилия по разработке. В определенной степени существует прямой компромисс между затратами на разработку или потерей денег на более мощном оборудовании.
Пример: свисающие ссылки
На практике вы должны смотреть не на информатику, а на требования своего бизнеса, чтобы понять, можно ли и как смягчить действие ACID. Например, многие отношения с внешними ключами могут быть не такими важными, как кажется. Рассмотрим товар - категория n: m отношений. В СУБД мы можем использовать ограничение внешнего ключа, чтобы только существующие продукты и существующие категории могли быть частью этих отношений. Что произойдет, если мы представим отдельные продукты и категории услуг, а продукт или категория будут удалены?
В этом случае это не может быть большой проблемой, и мы можем написать наше приложение, чтобы оно отфильтровывало любые продукты или категории, которые больше не существуют. Но есть компромиссы!
Обратите внимание, что для этого может потребоваться уровень приложения для JOIN
нескольких баз данных / микросервисов, который просто перемещает обработку с сервера базы данных в ваше приложение. Это увеличивает общую нагрузку и требует перемещения дополнительных данных по сети.
Это может испортить нумерацию страниц. Например, вы запрашиваете следующие 25 продуктов из категории и отфильтровываете недоступные продукты из этого ответа. Теперь ваше приложение отображает 23 продукта. Теоретически, страница с нулевым товаром также возможна!
Вы можете периодически запускать скрипт, который очищает висячие ссылки, либо после каждого соответствующего изменения, либо через регулярные промежутки времени. Обратите внимание, что такие сценарии довольно дороги, потому что они должны запрашивать каждый продукт / категорию из резервной базы данных / микросервиса, чтобы увидеть, существует ли он по-прежнему.
Это должно быть очевидно, но для ясности: не используйте идентификаторы повторно. Идентификаторы в стиле автоинкремента могут подойти или не подойти. GUID или хэши дают вам большую гибкость, например, возможность назначать идентификатор до того, как элемент будет вставлен в базу данных.
Пример: одновременные заказы
Теперь вместо этого рассмотрим отношения продукта с заказом. Что происходит с заказом, если товар удален или изменен? Хорошо, мы можем просто скопировать данные соответствующего продукта в запись заказа, чтобы сохранить их доступность - для простоты торгуем дисковым пространством. Но что, если цена продукта изменится или продукт станет недоступным непосредственно перед тем, как будет сделан заказ на этот продукт? В распределенной системе для распространения эффектов требуется время, и порядок, скорее всего, будет соответствовать устаревшим данным.
Опять же, как подойти к этому, зависит от ваших бизнес-требований. Может быть, устаревший заказ приемлем, и вы можете позже отменить заказ, если он не может быть выполнен.
Но, возможно, это не вариант, например, для одновременных настроек. Рассмотрим 3000 человек, спешащих купить билеты на концерты в течение первых 10 секунд, и давайте предположим, что для изменения доступности потребуется 10 мс. Какова вероятность продажи последнего билета нескольким людям? Зависит от того, как обрабатываются эти коллизии, но используя распределение Пуассона, λ = 3000 / (10s / 10ms) = 3
мы получаем P(k > 1) = 1 - P(k = 0) - P(k = 1) = 80%
шанс коллизии за интервал 10 мс. Возможность продажи и последующей отмены большинства ваших заказов без мошенничества может привести к интересному разговору с вашим юридическим отделом.
Прагматизм означает сбор лучших черт.
Хорошей новостью является то, что вам не нужно переходить на модель распределенной базы данных, если это не требуется в противном случае. Никто не отменит ваше членство в Микросервисном клубе, если вы не будете «правильно» использовать микросервисы, потому что такого клуба нет - и нет единственно верного способа создания микросервисов.
Прагматизм побеждает каждый раз, поэтому смешивайте и сочетайте различные подходы, поскольку они решают вашу проблему. Это может даже означать микросервисы с централизованной базой данных. На самом деле, не проходите через боль распределенных баз данных, если вам не нужно.
Вы можете масштабировать без микросервисов.
Микросервисы имеют два основных преимущества:
- Организационное преимущество заключается в том, что они могут разрабатываться и развертываться независимо отдельными группами (что, в свою очередь, требует от служб обеспечения стабильного интерфейса).
- Преимущество эксплуатации заключается в том, что каждый микросервис может масштабироваться независимо .
Если независимое масштабирование не требуется, микросервисы менее привлекательны.
Сервер базы данных уже является своего рода сервисом, который можно масштабировать (несколько) независимо, например, добавляя реплики чтения. Вы упоминаете хранимые процедуры. Сокращение их может иметь такой большой эффект, что любые другие дискуссии о масштабируемости будут спорными.
И вполне возможно иметь масштабируемый монолит, который включает все сервисы в виде библиотек. Затем вы можете масштабировать, запустив больше экземпляров монолита, что, конечно, требует, чтобы каждый экземпляр был без сохранения состояния.
Это имеет тенденцию работать хорошо, пока монолит не станет слишком большим, чтобы его можно было разумно развернуть, или если у некоторых служб есть особые требования к ресурсам, так что вы можете захотеть масштабировать их независимо. Проблемные области, которые требуют дополнительных ресурсов, могут не включать отдельную модель данных.
У вас есть сильное экономическое обоснование?
Вы знаете о бизнес-потребностях вашей организации и поэтому можете создать аргумент для архитектуры базы данных на микросервис на основе анализа:
- что требуется определенный масштаб, и эта архитектура является наиболее экономически эффективным подходом для достижения этой масштабируемости с учетом возросших усилий по разработке такой установки и альтернативных решений; и
- что ваши бизнес-требования позволяют ослабить соответствующие гарантии ACID, не приводя к различным проблемам, подобным тем, которые обсуждались выше.
И наоборот, если вы не можете продемонстрировать это, в частности, если текущая структура базы данных способна поддерживать достаточный масштаб в будущем (как полагают ваши коллеги), то у вас также есть свой ответ.
Существует также большой компонент YAGNI для масштабируемости. В условиях неопределенности это стратегическое бизнес-решение по созданию масштабируемости сейчас (снижение общих затрат, но включает альтернативные затраты и может не потребоваться) вместо того, чтобы откладывать некоторую работу по масштабируемости (более высокие общие затраты, если это необходимо, но у вас лучше представление о реальных масштабах). Это не в первую очередь техническое решение.