Шаблоны данных, ориентированные на облако

Как мы видели в этой книге, подход с использованием собственного облака изменяет способ проектирования, развертывания и управления приложениями. Он также изменяет способ управления и хранения данных.

На рис. 5-1 различают различия.

Хранение данных в собственных приложениях в облаке

Рис. 5-1. Управление данными в собственных облачных приложениях

Опытные разработчики легко распознают архитектуру на левой стороне рис. 5-1. В этом монолитном приложении компоненты бизнес-службы объединяются в общий уровень служб, совместно используя данные из одной реляционной базы данных.

Во многих случаях единая база данных обеспечивает простоту управления данными. Запрос данных по нескольким таблицам прост. Изменения в данных обновляются вместе или во всех операциях отката. Транзакции ACID гарантируют строгую и немедленную согласованность.

Разработка для собственного облака, мы принимаем другой подход. На правой стороне рис. 5-1 Обратите внимание на то, как бизнес-функции разделяются на небольшие независимые микрослужбы. Каждая микрослужба включает в себя определенную бизнес-возможность и собственные данные. Монолитная база данных разбивается на распределенную модель данных с несколькими меньшими базами данных, каждая из которых соответствует микрослужбе. После того, как этот тест очищен, мы создаем проект, который предоставляет базу данных для каждой микрослужбы.

Зачем нужна база данных для микрослужбы?

Эта база данных на микрослужбах предоставляет множество преимуществ, особенно для систем, которые должны быстро развиваться и поддерживать крупномасштабное масштабирование. С этой моделью...

  • Данные домена инкапсулируются в службе
  • Схема данных может развиваться без непосредственного воздействия на другие службы
  • Каждое хранилище данных может масштабироваться независимо друг от друга
  • Сбой хранилища данных в одной службе не влияет на другие службы напрямую.

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

На рисунке 5-2 представлен принцип polyglot persistence в собственной облачной системе.

Сохраняемость данных Polyglot

Рис. 5-2. Сохраняемость данных Polyglot

Обратите внимание, что на предыдущем рисунке каждая микрослужба поддерживает различные типы хранилищ данных.

  • Микрослужба каталога продукции использует реляционную базу данных для обеспечения функциональной реляционной структуры базовых данных.
  • Микрослужба корзины для покупок использует распределенный кэш, который поддерживает простое хранилище данных "ключ — значение".
  • Микрослужба заказа использует базу данных документов NoSql для операций записи, а также строго денормализованное хранилище ключей и значений для поддержки больших объемов операций чтения.

В то время как реляционные базы данных остаются актуальными для микрослужб со сложными данными, NoSQL базы данных значительно популярность. Они обеспечивают широкие возможности масштабирования и обеспечения высокого уровня доступности. Их природа без схем позволяет разработчикам переходить от архитектуры типизированных классов данных и моделей ORM, которые делают изменения затратными и ресурсоемкими. Далее в этой главе мы рассмотрим базы данных NoSQL.

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

Запросы между службами

Хотя микрослужбы независимы и сосредоточены на конкретных функциональных возможностях, таких как Инвентаризация, Доставка или упорядочение, для них часто требуется интеграция с другими микрослужбами. Часто интеграция состоит в том, что одна микрослужба запрашивает другие данные. На рис. 5-3 показан сценарий.

Запросы между микрослужбами

Рис. 5-3. Запросы между микрослужбами

На предыдущем рисунке показана микрослужба корзины покупок, которая добавляет элемент в корзину для покупок пользователя. Хотя хранилище данных для этой микрослужбы содержит данные элементов корзины и строк, оно не поддерживает данные о продуктах и ценах. Вместо этого эти элементы данных принадлежат микрослужбам каталога и ценообразования. Этот аспект представляет проблему. Как микрослужба корзины покупок добавляет продукт к корзине покупок пользователя, если в базе данных нет данных о продукте или ценах?

Один из вариантов, описанных в главе 4, — прямой вызов HTTP из корзины покупок в микрослужбы каталога и ценообразования. Однако в главе 4 мы говорили о синхронных HTTP- вызовах , объединяющих микрослужбы, уменьшая их автономность и снижая преимущества архитектуры.

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

Вместо этого широко принятым шаблоном для удаления зависимостей между службами является Материализованный шаблон представления, показанный на рис. 5-4.

Шаблон материализованных представлений

Рис. 5-4. Шаблон материализованных представлений

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

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

Распределенные транзакции

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

На рис. 5-5 показана проблема.

Транзакция в шаблоне Saga

Рис. 5-5. Реализация транзакции по микрослужбам

На предыдущем рисунке пять независимых микрослужб участвуют в распределенной транзакции, которая создает заказ. Каждая микрослужба поддерживает собственное хранилище данных и реализует локальную транзакцию для своего магазина. Чтобы создать заказ, локальная транзакция для каждой отдельной микрослужбы должна быть выполнена, либо все должно завершиться и откатить операцию. Хотя встроенная поддержка транзакций доступна в каждой микрослужбе, нет поддержки распределенной транзакции, охватывающей все пять служб для обеспечения согласованности данных.

Вместо этого распределенная транзакция должна создаваться программно.

Распространенный шаблон для добавления распределенной поддержки транзакций — шаблон Saga. Он реализуется с помощью группирования локальных транзакций вместе программно и последовательно вызывает каждый из них. Если какая-либо из локальных транзакций завершается ошибкой, Saga прерывает операцию и вызывает набор компенсирующих транзакций. Компенсирующие транзакции отменяют изменения, внесенные предыдущими локальными транзакциями, и восстанавливают согласованность данных. На рис. 5-6 показана неудачная транзакция с шаблоном Saga.

Откат в шаблоне Saga

Рис. 5-6. Откат транзакции

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

Шаблоны Saga обычно организуются как ряд связанных событий или организованы в виде набора связанных команд. В главе 4 мы обсуждали шаблон агрегатора служб, который будет основой для управляемой реализации Saga. мы также обсуждали события, связанные с служебная шина azure и таблицами службы "сетка событий azure", которые будут основой для реализации организуются saga.

Данные большого объема

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

CQRS

CQRS— это шаблон архитектуры, позволяющий максимально повысить производительность, масштабируемость и безопасность. Шаблон разделяет операции, считывающие данные из операций, которые записывают данные.

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

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

На рис. 5-7 показана реализация шаблона CQRS.

разделение команд и запросов

Рис. 5-7. Реализация CQRS

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

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

Реализация CQRS может улучшить производительность приложений для облачных служб. Однако это приводит к более сложной структуре. Применяйте этот принцип внимательно и стратегически к разделам собственного облачного приложения, которые повышают его преимущества. Дополнительные сведения о CQRS см. в статье о микрослужбах .NET книги Майкрософт: архитектура для контейнерных приложений .NET.

Источник событий

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

Как правило, система хранит текущее состояние сущности данных. Если пользователь изменяет свой номер телефона, например, запись клиента обновляется с учетом нового номера. Мы всегда знакомы с текущим состоянием сущности данных, но каждое обновление перезаписывает предыдущее состояние.

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

Источник событий использует другой подход к сбору данных. Каждая операция, влияющая на данные, сохраняется в хранилище событий. Вместо обновления состояния записи данных мы добавляем каждое изменение в последовательный список прошлых событий, как в бухгалтерскую книгу. Хранилище событий преобразуется в систему записи данных. Он используется для распространения различных материализованных представлений в ограниченном контексте микрослужбы. На рисунке 5,8 показан шаблон.

Источник событий

Рис. 5-8. Источник событий

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

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

Для этого шаблона рассмотрим хранилище данных, которое напрямую поддерживает источники событий. Azure Cosmos DB, MongoDB, Cassandra, CouchDB и RavenDB являются хорошими кандидатами.

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