Комментарии 39
1. Не беспокоитесь ли вы, что с ростом количества клиентов у вас будут проблемы с администрированием N баз данных?
2. Как вы шерите общие справочники, актуальные одновременно для всех тенантов?
3. Что такое «монолитные сервисы» и чем они отличаются от микросервисов в вашей интерпретации?
4. Вам не мешает жесткая привязка тенанта к потоку при выполнении асинхронного метода контроллера для http-запроса? Ведь при выполнении асинхронной операции неизвестно в каком потоке будет выполнен continuation после await.
Думаю, таким способом можно администрировать и несколько тысяч БД, если все массовые задачи автоматизировать.
Вы бы стали его использовать при проектировании multitennant-системы с нуля или всё же воспользовались бы идентификатором теннанта?
Минусы варианта, когда добавляем колонку «идентификатор тенанта» в каждую таблицу:
— в каждый запрос к БД нужно добавлять фильтр по тенанту
— в каждый индекс в БД нужно добавлять тенант в ключ
— есть таблицы, которые быстро растут в организациях (документы, задачи, права), если сейчас они как бы секционированы (у каждой организации своя БД с таблицами), то если данные организаций объединить запросы станут хуже по скорости (я про поисковые запросы по произвольным свойствам с учетом прав)
А еще мы действительно используем возможность перераспределения тенантов по стендам, т.е. когда данные одного тенанта переносятся на другой стенд.
А микросервисы (в контексте нашей системы) — это сервисы, у которых явно выделены одна-две ответственности. Их в принципе можно переписать за неделю.
Я говорил у нас 5 монолитных сервисов, но точнее будет так: у нас один монолит (платформа) и на ее базе 5 сервисов с разным АПИ.
private static readonly ThreadLocal<string> tenantId = new ThreadLocal<string>();
Потом сменили на:
private static readonly AsyncLocal<string> tenantId = new AsyncLocal<string>();
Представьте как это дело обновлять. Добавили колонку, а скрипт который обновляет схемы БД падает на каком-то тенанте.
Всем этим зоопарком придется как-то управлять, и почти наверняка чем-то своим самописным.
А еще билинг, еще отчеты. Как сделать выборку всех заказов всех клиентов для аналитики? Все это очень усложняет управление.
Обновлять стенды можно последовательно. Поэтому проблему, что обновление падает на конкретном тенанте (а проблема кстати существует), будет только для конкретного стенда.
Но то что придется рулить зоопарком в 100 стендов — это конечно напряг, нужны админы.
Отчеты производительности и ошибок — это уже автоматизировано. А отчетов по данным из БД организаций мы не собираем (я не слышал чтобы собирали), это же ECM-система.
рулить зоопарком в 100 стендов — это конечно напряг, нужны админы
Если сделать в одной большой БД — то их столько не надо. Значит если бы был владельцем, получил бы больше денег ;)
это же ECM-система
Надо же вам иметь статистику по кол-ву юзеров/документов во всех БД. Если бы я был вашим топ-менеджером, то спросил бы, на сколько мы выросли за год.
Куча БД — не масштабируемое решение.
Если сделать в одной большой БД — то их столько не надо.
Окей. А как вы будите масштабировать одну большую БД?
Если и этого будет мало, то значит мы уже не маленькая компания на 30 человек, а значит сможем позволить себе специалистов которые подскажут-расскажут-сделают.
Вспомните что было с ОК.ру и как он тормозил. Они выросли, переписали все внутри, перенесли данные и сейчас всё у них хорошо. Мне кажется это правильным подходом.
Реплики на чтение, не решают проблему шумных соседей. Её можно решить только выносом этих клиентов на отдельные инстансы.
В место архитектуры в которой заложена запас прочности в виде выноса на отельные инстансы, вы предлагаете взять и всё переписать?
запас прочности в виде выноса на отельные инстансы
Дело в том что подход с колонками tenantid — можно расширить на отдельные инстансы, путем вывода «жирных» клиентов по другим серверам.
А вот подход multyinstance множество мелких клиентов уже никак не объединить в один сервер.
Понимаете, я могу объяснить бизнесу, что клиент приносящий несколько тысяч долларов в месяц требует дополнительный сервер, но почему на каждого мелкого клиента с совокупным доходом несколько десятков долларов, мы должны поддерживать для него базу/инстанс — с трудом.
В место архитектуры в которой заложена запас прочности в виде выноса на отельные инстансы, вы предлагаете взять и всё переписать?
Закладывание этой прочности в архитектуру сейчас, когда там и так справляется одна машина, на мой взгляд лишнее.
Эта архитектура (СЕЙЧАС) лишь дополнительная уйма работы для DBA и DevOps. На ровном месте создали постоянные издержки для компании только из-за предположения что когда тенанты начнут сильно расти, мы легко с этим справимся.
Когда все тенанты в одной БД, то не сильно сложно склонировать схему, забить её только данными нагруженного тенанта и отправить эту отдельную БД на свою отдельную железку.
Вопрос лишь в деньгах.
Шардинг как раз таки решает проблему когда один тенант больше остальных грузит инстанс БД
А теперь представь тысячи клиентов на одном бд сервере)
Одна активная СУБД + два активных сервера приложений в пике держат до 400 запросов в секунду (в среднем 70-100).
Если бы у нас была мульти БД архитектура — я бы повешался.
Справедливо ли это? Когда у вас для каждого клиента своя БД, то вы можете этим управлять и выносить наиболее нагруженных клиентов на отдельные сервера.
все клиенты оказывают нагрузку на одну и ту же БД
Это сильно зависит от самого приложения и бизнес процессов. Если есть очень много мелких клиентов и несколько крупных, то проще — мелочь сложить в одну базу, а крупным выделить свой instance бд/сервисов/сайтов и т.д.
Если прямо завтра надо решать эту задачу, я сделаю бэкап базы, подниму новый сервер с клоном (со всем тенантами) и перенесу нагрузку на новую СУБД. Да, будет проблема назад всё это слить, но ведь нам надо бизнес делать, а не придумывать идеальные схемы :)
Почему в качестве конфигурации тенантов файл, а не отдельная общая бд + кеш? Это было бы проще чем распростронять файл по куче серверов
100 таблиц? Насколько я помню Директум, почти всё в одной гигантской таблице лежит, с миллионом колонок.
Чем не понравился подход "schema per tenant"?
Годная статья, у нас такое же решение получилось с доменами, логированием и с подходом, что бизнес код работает всегда в контексте конкретного тенанта и не видит чужие данные.
Правда таблицы у нас общие. В каждой таблице есть первичный ключ (tenant_id, id) и в случае необходимости можно вынести отдельного клиента в отдельную бд.
Как сделать из не тенантного приложения мультитенантное