Что такое мультитенантность?
Мультитенантная архитектура позволяет нескольким клиентам использовать одну инфраструктуру и приложение одновременно, сохраняя изоляцию данных. Tenant переводится как «арендатор», отражая принцип совместного использования ресурсов с сохранением приватности для каждого «арендатора». Таким образом, каждый клиент может получить доступ к своим данным и настройкам, не влияя на других клиентов.
Мультитенантная архитектура упрощает процесс масштабирования за счет использования общего пула ресурсов, благодаря чему система обретает гибкость и готовность к росту.
Зачем внедрять мультитенантность
Традиционный подход в SaaS-приложениях для B2B предполагает выделение отдельного инстанса приложения для каждого клиента. Такой подход требует значительных ресурсов для поддержки инфраструктуры, но ведет к существенным дополнительным расходам. Мультитенантная архитектура позволяет оптимизировать использование ресурсов, предоставляя общий инстанс приложения для всех клиентов с сохранением их изоляции и безопасности данных. Внедрение мультитенантности в нашем случае было обусловлено рядом факторов.
Во-первых, поддержка большого количества клиентов требовала множества отдельных операций по мониторингу, обслуживанию и обновлениям. Каждая такая операция отнимала у команды время и ресурсы и замедляла общее развитие системы. Мультитенантная архитектура позволяет централизовать процессы обслуживания.
Во-вторых, необходимость поддерживать инфраструктуру для всех клиентов с учетом пиковых нагрузок приводила к высоким затратам. В условиях традиционной архитектуры каждому клиенту выделялись собственные ресурсы для обеспечения стабильной работы, что увеличивало расходы на инфраструктуру. Переход на мультитенантность позволяет использовать общие ресурсы более эффективно.
Третьим важным фактором стала поддержка пробного периода для клиентов. Бесплатные пробные доступы создают дополнительные расходы для поставщика, что снижает рентабельность. В условиях мультитенантной архитектуры можно предоставить доступ к системе новым пользователям без создания дополнительных инстансов.
Наконец, традиционная модель оказалась недостаточно масштабируемой. По мере роста количества клиентов и их требований, система становилась всё более сложной в обслуживании и масштабировании.
Как я внедрял мультитенантность
В моем случае переход на мультитенантную архитектуру подразумевал не создание нового продукта, а преобразование уже существующего решения с архитектурой «1 инстанс = 1 клиент». Это усложнило задачу и потребовало тщательного планирования на каждом этапе.
Мы определили три ключевые задачи: аутентификацию пользователей, разделение данных клиентов и организацию структуры данных. Давайте подробно рассмотрим, как мы решали каждую из них.
Аутентификация пользователей
В традиционной архитектуре, где каждому клиенту выделяется отдельный инстанс приложения, аутентификация проще, так как у каждого клиента своя изолированная система. Но в мультитенантной архитектуре, где все клиенты работают в одной системе, нужно было обеспечить четкое разделение пользователей и гарантировать, что каждый из них имеет доступ только к своим данным, ведь ошибки в аутентификации чреваты утечками и проблемами с безопасностью.
Мы рассматривали несколько вариантов организации аутентификации:
- Сквозная аутентификация с уникальными URL для каждого клиента: При этом каждый клиент получает свой уникальный URL, что позволяет системе автоматически идентифицировать клиента и облегчает доступ к данным.
- Один URL и контекстно-зависимая аутентификация: Все клиенты используют один URL для входа, и система определяет, к каким данным должен быть доступ в зависимости от контекста пользователя (на основе учетных данных и токенов).
Мы остановились на первом варианте. Этот подход лучше изолирует клиентов и упрощает процесс входа в систему и снижает вероятность ошибок, связанных с неправильной идентификацией клиента. Кроме того, такой подход хорошо масштабируется при увеличении числа клиентов.
Реализация сквозной аутентификации значительно упростила процесс логина для клиентов и повысила уровень безопасности. Каждый клиент теперь имеет уникальный URL, что минимизирует риск доступа к данным других клиентов. Этот подход также упростил поддержку и сократил время на устранение ошибок, связанных с доступом к данным.
Разделение данных клиентов
В классической архитектуре, когда у каждого клиента отдельный инстанс приложения, данные уже изолированы. Но в мультитенантной архитектуре все данные хранятся в одном приложении.Необходимо было гарантировать, что каждый клиент может видеть только свои данные, и что доступ к чужим данным был исключен.
Для разделения данных клиентов мы изучили следующие подходы:
- Контекстно-зависимая фильтрация данных: Данные фильтруются в зависимости от контекста запроса, и система автоматически выбирает только те данные, которые принадлежат текущему клиенту.
- Явное указание клиентского контекста: Каждому запросу данных присваивается уникальный клиентский идентификатор, и все запросы обрабатываются в рамках этого контекста. Это позволяет системе строго следить за тем, что каждому клиенту возвращаются только его данные.
Мы выбрали второй подход с явным указанием клиентского контекста, так как он обеспечивает более высокую степень безопасности и прозрачности. Этот подход позволяет отслеживать и логировать все обращения к данным, что упрощает аудит и контроль за безопасностью. Также он помогает предотвратить случайные ошибки при обработке запросов, поскольку система строго привязывает каждый запрос к конкретному клиенту.
Введение строгого клиентского контекста обеспечило высокий уровень безопасности и помогло избежать утечек данных между клиентами. Доверие со стороны клиентов выросло, так как их данные теперь были гарантированно защищены и изолированы. Помимо этого, упрощение мониторинга запросов позволило DevOps-команде быстрее выявлять потенциальные проблемы.
Организация структуры данных
В мультитенантной архитектуре структура хранения данных должна учитывать изоляцию данных для каждого клиента, но также должна быть эффективной и масштабируемой. Классическая архитектура с отдельными базами данных для каждого клиента становится слишком дорогой и сложной в обслуживании, а объединение данных всех клиентов в общих таблицах может привести к снижению производительности и увеличению риска ошибок.
Мы рассмотрели сразу три подхода к организации хранения данных:
- Объединение данных в общие таблицы: Данные всех клиентов хранятся в общих таблицах, но каждый клиент идентифицируется с помощью уникальных значений. Этот подход упрощает инфраструктуру, но требует высокой осторожности в выполнении запросов и увеличивает риск ошибок.
- Отдельные базы данных для каждого клиента: Этот вариант обеспечивает полную изоляцию данных и упрощает вопросы безопасности, но требует значительных ресурсов и сложно масштабируется.
- Одна база данных с множеством схем: В этом случае данные каждого клиента хранятся в отдельной схеме в рамках одной базы данных. Это позволяет изолировать данные клиентов и одновременно использовать преимущества единой базы данных для простоты администрирования.
В итоге был выбран вариант с одной базой данных и множеством схем, поскольку он оказался оптимальным решением. Этот подход позволил изолировать данные каждого клиента на уровне схем, сохраняя возможность использования JOIN-ов и внешних ключей между таблицами, а это значительно упростило администрирование и ускорило выполнение запросов. Также этот вариант лучше подошел для нужд масштабирования.
Благодаря этому подходу стало проще добавлять новых клиентов и обрабатывать данные с высокой производительностью. Этот подход также минимизировал трудозатраты на поддержку, так как один DevOps-специалист может управлять всей инфраструктурой. В итоге расходы на инфраструктуру сократились в 20 раз.
Итоги использования мультитенантной архитектуры
- Автоматическая регистрация клиентов: Теперь клиенты могут регистрироваться и начинать работу без участия команды внедрения.
- Снижение затрат на инфраструктуру: Благодаря мультитенантности, расходы на инфраструктуру сократились в 20 раз, так как общий пул ресурсов стал использоваться более эффективно.
- Минимизация трудозатрат на поддержку: Вся инфраструктура поддерживается всего одним DevOps-специалистом, что значительно упрощает управление и позволяет компании оптимизировать расходы.
Ключевые выводы и рекомендации
На основе полученного опыта, команда пришла к следующим выводам:
- Универсального решения не существует: Выбор архитектуры зависит от множества факторов, таких как количество клиентов, требования к безопасности, возможности масштабирования и бюджет на инфраструктуру.
- Комплексность всегда требует компромиссов: Важно помнить, что стремление к идеалу может затормозить развитие. Выбранный подход должен быть оптимальным для текущих нужд, а не для гипотетических сценариев.
- Невозможно предусмотреть всё заранее: При внедрении мультитенантной архитектуры важно иметь гибкость для адаптации к новым требованиям и изменениям в технологии.
Заключение
Мультитенантная архитектура предоставляет SaaS-компаниям возможность гибкого масштабирования и эффективного использования ресурсов. В моем случае внедрение этого подхода позволило улучшить стабильность и производительность системы, а также заметно сократить затраты на инфраструктуру. Однако переход на мультитенантность требует внимательной проработки архитектуры и оценки всех возможных рисков.
Для компаний, которые рассматривают мультитенантность, мы рекомендуем:
- Тщательно анализировать потребности клиентов: Прежде чем выбирать архитектуру, важно понять, какие данные и процессы действительно требуют изоляции.
- Заложить гибкость в систему: Система должна быть готова к изменениям, поскольку требования могут меняться по мере роста компании.
- Уделить внимание обучению команды: Внедрение мультитенантности требует не только технической компетенции, но и умения адаптироваться и работать в условиях постоянных изменений.
Мультитенантная архитектура в SaaS-приложениях может стать мощным инструментом для компаний, которые стремятся к росту и оптимизации инфраструктурных затрат.
Комментарии