Реализация мультиарендной архитектуры с PostgreSQL: Изучение на простом примере из реальной жизни
Узнайте, как реализовать мультиарендную архитектуру с PostgreSQL Row-Level Security (RLS) и ролями базы данных через пример из реальной жизни для безопасной изоляции данных между арендаторами.
В некоторых из наших предыдущих статей мы углублялись в концепцию мультиарендности и её применение в продуктах и реальных бизнес-сценариях.
В этой статье мы рассмотрим, как реализовать мультиарендную архитектуру для вашего приложения, используя PostgreSQL с технической точки зрения.
Что такое одноарендная архитектура?
Одноарендная архитектура относитс я к программной архитектуре, где каждый клиент имеет своё собственное выделенное экземпляр приложения и базы данных.
В этой архитектуре данные и ресурсы каждого арендатора полностью изолированы от других арендаторов.
Что такое мультиарендная архитектура?
Мультиарендная архитектура — это программная архитектура, где несколько клиентов (арендаторов) используют один и тот же экземпляр приложения и инфраструктуры, обеспечивая при этом изоляцию данных. В этой архитектуре один экземпляр программного обеспечения обслуживает нескольких арендаторов, и данные каждого арендатора отделены от других через различные механизмы изоляции.
Одноарендная архитектура vs мультиарендная архитектура
Одноарендная архитектура и мультиарендная архитектура отличаются в таких аспектах, как изоляция данных, использование ресурсов, масштабируемость, управление и обслуживание, а также безопасность.
В одноарендной архитектуре каждый клиент имеет независимое пространство данных, что приводит к низкому использованию ресурсов, но относительно проще для кастомизации. Обычно одноарендное программное обеспечение подстраивается под конкретные потребности клиента, такие как системы управления запасами для определенного поставщика тканей или персональный веб-приложение для ведения блогов. Общим для них является то, что каждый клиент занимает отдельный экземпляр службы приложения, что облегчает кастомизацию для удовлетворения конкретных требований.
В мультиарендной архитектуре несколько арендаторов делят одни и те же ресурсы, что приводит к более эффективному использованию ресурсов. Однако важно обеспечить изоляцию данных и безопасность.
Мультиарендная архитектура часто является предпочтительной программной архитектурой, когда поставщики услуг предлагают стандартизированные услуги различным клиентам. Эти услуги, как правило, имеют низкий уровень кастомизации, и все клиенты используют один и тот же экземпляр приложения. Когда приложению требуется обновление, обновление одного экземпляра приложения равнозначно обновлению приложения для всех клиентов. Например, CRM (Управление Взаимоотношениями с Клиентами) — это стандартизированное требование. Эти системы обычно используют мультиарендную архитектуру для предоставления одной и той же услуги всем арендаторам.
Стратегии изоляции данных арендаторов в мультиарендной архитектуре
В мультиарендной архитектуре все арендаторы используют одни и те же ресурсы, поэтому изоляция ресурсов между арендаторами важна. Эта изоляция не обязательно должна быть физической; достаточно, чтобы ресурсы между арендаторами были невидимы друг для друга.
В дизайне архитектуры можно достичь различных степеней изоляции ресурсов между арендат орами:
В общем, чем больше ресурсов делится между арендаторами, тем ниже стоимость итерации и обслуживания системы. И наоборот, чем меньше ресурсов делится, тем выше стоимость.
Начало реализации мультиарендности на примере из реальной жизни
В этой статье мы будем использовать систему CRM в качестве примера, чтобы представить простую, но практичную мультиарендную архитектуру.
Мы признаем, что все арендаторы используют одни и те же стандартизированные услуги, поэтому решили, что все арендаторы будут делить одни и те же базовые ресурсы, и мы реализуем изоляцию данных между различными арендаторами на уровне базы данных, используя Row-Level Security PostgreSQL.
Кроме того, мы создадим отдельное подключение к данным для каждого арендатора, чтобы облегчить управление разрешениями арендаторов.
Далее мы расскажем, как реализовать эту мультиарендную архитектуру.
Как реализовать мультиарендную архитектуру с PostgreSQL
Добавление идентификатора арендатора ко всем ресурсам
В системе CRM у нас будет много ресурсов, которые хранятся в разных таблицах. Например, информация о клиентах хранится в таблице customers
.
До реализации мультиарендности эти ресурсы не связаны с каким-либо арендатором:
Чтобы различать арендаторов, владеющих разными ресурсами, мы вводим таблицу tenants
для хранения информации о арендаторах (где db_user
и db_user_password
используются для хранения информации о подключении к базе данных для каждого арендатора, это будет подробно описано ниже). Кроме того, мы добавляем поле tenant_id
к каждому ресурсу, чтобы идентифицировать, к какому арендатору он принадлежит:
Теперь каждый ресурс связан с tenant_id
, теоретически позволяя нам добавлять условие where
ко всем запросам, чтобы ограничить доступ к ресурсам для каждого арендатора:
На первый взгляд, это кажется простым и осуществимым. Однако это вызовет следующие проблемы:
- Почти каждый запрос будет включать это условие
where
, загромождая код и усложняя его обслуживание, особенно при написании сложных операторов объединения. - Новички в кодовой базе могут легко забыть добавить это условие
where
. - Данные между различными арендаторами не изолированы на самом деле, так как каждый арендатор все еще имеет разрешение на доступ к данным, принадлежащим другим арендаторам.
Поэтому мы не будем использовать этот подход. Вместо этого мы будем использовать Row Level Security PostgreSQL для решения этих проблем. Однако прежде чем продолжить, мы создадим выделенную учетную запись базы данных для каждого арендатора для доступа к этой общей базе данных.
Настройка ролей базы данных для арендаторов
Практика показывает, что хорошо назначить роль базы данных каждому пользователю, который может подключаться к базе данных. Это позволяет лучше контролировать доступ каждого пользователя к базе данных, содействуя изоляции операций между различными пользователями и улучшая стабильность и безопасность системы.
Поскольку у всех арендаторов одинаковое разрешение на операции с базой данных, мы можем создать базовую роль для управления этими разрешениями:
Затем, чтобы различать роли каждого арендатора, при создании для каждого арендатора назначается роль, наследуемая от базовой роли:
Далее информация о подключении к базе данных для каждого арендатора будет храниться в таблице tenants
:
id | db_user | db_user_password |
---|---|---|
x2euic | crm_tenant_x2euic | pa55w0rd |
Этот механизм предоставляет каждому арендатору свою роль в базе данных, и эти роли разделяют права, предоставленные роли crm_tenant
.