С подходом «БД на тенант» получалось проще администрирование (проще чем с «schema per tenant»). Админу проще перенести БД на другой облачный стенд (т.е. перераспределить тенанты по стендам), проще забэкапить и восстановить бэкап конкретной организации. Проще узнать объем памяти занимаемой БД. Т.е. такой единицей как БД манипулировать удобнее.
Что касается конфигурирования, то очень хочется какое-то общее хранилище всех настроек. И скорее всего это не БД, а еще что-то более специализированное. Возможно отдельный сервис.
Но с файлами было проще (так исторически сложилось)
Тенанты мы объединяем в группы: 80 тенантов на стенд, размер одной БД ~5 Гб, суммарный объем баз ~400 Гб. Это значит 10000 тенантов будут разбиты на ~100 стендов.
Обновлять стенды можно последовательно. Поэтому проблему, что обновление падает на конкретном тенанте (а проблема кстати существует), будет только для конкретного стенда.
Но то что придется рулить зоопарком в 100 стендов — это конечно напряг, нужны админы.
Отчеты производительности и ошибок — это уже автоматизировано. А отчетов по данным из БД организаций мы не собираем (я не слышал чтобы собирали), это же ECM-система.
У нас не было проблем, что большая система не позволяла реализовать другие схемы работы с тенантами. Мы могли в каждую колонку БД добавить идентификатор тенанта. Выбор был осмысленный. У выбранной схемы было больше плюсов. Поэтому даже сейчас для этой системы я бы сделал такой же выбор.
Минусы варианта, когда добавляем колонку «идентификатор тенанта» в каждую таблицу:
— в каждый запрос к БД нужно добавлять фильтр по тенанту
— в каждый индекс в БД нужно добавлять тенант в ключ
— есть таблицы, которые быстро растут в организациях (документы, задачи, права), если сейчас они как бы секционированы (у каждой организации своя БД с таблицами), то если данные организаций объединить запросы станут хуже по скорости (я про поисковые запросы по произвольным свойствам с учетом прав)
А еще мы действительно используем возможность перераспределения тенантов по стендам, т.е. когда данные одного тенанта переносятся на другой стенд.
4. Да, с такой проблемой мы сталкивались. Тут все зависит от того как реализовать привязку. Вначале мы делали привязку так и в какой-то момент получили проблемы:
private static readonly ThreadLocal<string> tenantId = new ThreadLocal<string>();
Потом сменили на:
private static readonly AsyncLocal<string> tenantId = new AsyncLocal<string>();
3. Монолитные (в контексте нашей системы) — это сервисы, в которых большой объем кода, наверное, близко к миллиону строк. Их писали годами, у них много ответственностей (функционала). Один человек не может держать в голове детали по всему функционалу.
А микросервисы (в контексте нашей системы) — это сервисы, у которых явно выделены одна-две ответственности. Их в принципе можно переписать за неделю.
Я говорил у нас 5 монолитных сервисов, но точнее будет так: у нас один монолит (платформа) и на ее базе 5 сервисов с разным АПИ.
2. Общие справочники мы дублируем. У каждого тенанта своя копия записей. Но таких справочников не много, место занимают мало. Это города, страны, регионы, системные роли и пользователи, журналы регистрации…
1. На один облачный стенд у нас приходится около 80 тенантов (80 БД). Таких стендов несколько. Есть еще выделенные стенды для крупных компании, где только 1 БД. Администрировать все БД руками не реально. Поэтому все основные задачи автоматизируются скриптами и джобами (выполняются массово для всех БД) — бэкапы, обновления структуры БД. И админ не один — несколько.
Думаю, таким способом можно администрировать и несколько тысяч БД, если все массовые задачи автоматизировать.
Проблему поняли правильно. Компилирую WPF приложение, написанное на .NET Core 3.0, под нужную ОС, делаю ее «self-contained». Отдаю пользователю приложение. У пользователю стоит net
framework 4.5/4.6. WPF приложение заработает?
Получается после перевода wpf приложения на .net core всем пользователям нужно будет поднять версию net framework на 4.7? А что делать если это не допустимо заставлять всех пользователей обновлять фреймворк?
Не понятно как использовать императивное управление. У нас скроллингом в гриде управляют вообще из других компонент, которые не в курсе, где этот грид находится. Может он даже не отрисован. Да, и не держать же ссылку на грид в Store.
Можно, конечно, пойти от кейсов. И убедить, что наши кейсы можно закрыть и без управления скроллингом. Например, один кейс — это скроллиться к выделению при смене выделения (но не всегда, есть исключения). Намного проще разрешить управление и все кейсы закрыть через явное управление)
По поводу scrollSignal. Перед публикацией эту статью прочли в моем отделе, и сказали «что за хак, нельзя эту проблему по другому было решить?». Да, воспринимается это хаком. Но с текущим решением у меня не было боли и агонии, нормально взлетело, но с популяризацией тяжело.
По поводу чистить scrollToIndex после скроллинга: можно попробовать. В теории между установкой scrollToIndex и сбросом, может еще кто-то вклинится с желанием установить свое значение scrollToIndex, и важное не сбросить его, случайно. Надо потестировать, может и нет проблем. А вообще, хорошая идея, попробую как-нибудь на другом функционале.
Давно хотим выложить грид в публичный доступ. Организационно проблем нет. Но есть проблемы с трудоемкостью: выделить его в отдельный проект, отвязать от нашей платформы, от завязок на некоторые компоненты (надо часов 50). Трудоемкость оценили, но времени нам пока на это не дали
На прототипирование основных механизмов (виртуализация, работа с колонками, проционно загружаемые данные) потратили ~80 чч (человеко-часов). Два человека в течении недели полный рабочий день.
А затем составили детальный список всех работ, и это оказался очень большой список:
работа с redux, выделение, навигация, фокус, удаление-добавление записей, проверка инконсистентности, сокращение числа запросов при первом открытии, стили колонок/строк, работа с колонками (растягивание/перестановка/скрытие/сортировка/запрет перестановки), нет данных, выравнивание теста, триминг, контекстные меню, количество записей, поддержка автотестов, фильтры по колонкам, like-поиск, сохранение/восстановление настроек.
Все это делали долго, наверное, полгода. Примерно ~500 чч
В итоге по трудоемкости мы вложились сильно в грид. Компания нам такую возможность дала — отказаться от DevExtreme и все переписать.
Не смотрели.
У нас в отделе прослеживается такая тенденция: берем стороннюю компоненту, понимаем что нас не устраивает ее внешний вид, поведение, работа с клавиатурой, фокусом, не хватает каких-либо возможностей. И начинаем все вылизывать, докручивать, переделывать в этой компоненте, учить ее работать с тем с чем она не умеет работать. И это не разовая работа, по ходу развития проекта появляются новые требования к уже используемым компонентам.
Это тоже сыграло роль в принятии решения.
Но с файлами было проще (так исторически сложилось)
Обновлять стенды можно последовательно. Поэтому проблему, что обновление падает на конкретном тенанте (а проблема кстати существует), будет только для конкретного стенда.
Но то что придется рулить зоопарком в 100 стендов — это конечно напряг, нужны админы.
Отчеты производительности и ошибок — это уже автоматизировано. А отчетов по данным из БД организаций мы не собираем (я не слышал чтобы собирали), это же ECM-система.
Минусы варианта, когда добавляем колонку «идентификатор тенанта» в каждую таблицу:
— в каждый запрос к БД нужно добавлять фильтр по тенанту
— в каждый индекс в БД нужно добавлять тенант в ключ
— есть таблицы, которые быстро растут в организациях (документы, задачи, права), если сейчас они как бы секционированы (у каждой организации своя БД с таблицами), то если данные организаций объединить запросы станут хуже по скорости (я про поисковые запросы по произвольным свойствам с учетом прав)
А еще мы действительно используем возможность перераспределения тенантов по стендам, т.е. когда данные одного тенанта переносятся на другой стенд.
Потом сменили на:
А микросервисы (в контексте нашей системы) — это сервисы, у которых явно выделены одна-две ответственности. Их в принципе можно переписать за неделю.
Я говорил у нас 5 монолитных сервисов, но точнее будет так: у нас один монолит (платформа) и на ее базе 5 сервисов с разным АПИ.
Думаю, таким способом можно администрировать и несколько тысяч БД, если все массовые задачи автоматизировать.
framework 4.5/4.6. WPF приложение заработает?
Получается после перевода wpf приложения на .net core всем пользователям нужно будет поднять версию net framework на 4.7? А что делать если это не допустимо заставлять всех пользователей обновлять фреймворк?
Можно, конечно, пойти от кейсов. И убедить, что наши кейсы можно закрыть и без управления скроллингом. Например, один кейс — это скроллиться к выделению при смене выделения (но не всегда, есть исключения). Намного проще разрешить управление и все кейсы закрыть через явное управление)
По поводу scrollSignal. Перед публикацией эту статью прочли в моем отделе, и сказали «что за хак, нельзя эту проблему по другому было решить?». Да, воспринимается это хаком. Но с текущим решением у меня не было боли и агонии, нормально взлетело, но с популяризацией тяжело.
По поводу чистить scrollToIndex после скроллинга: можно попробовать. В теории между установкой scrollToIndex и сбросом, может еще кто-то вклинится с желанием установить свое значение scrollToIndex, и важное не сбросить его, случайно. Надо потестировать, может и нет проблем. А вообще, хорошая идея, попробую как-нибудь на другом функционале.
А затем составили детальный список всех работ, и это оказался очень большой список:
работа с redux, выделение, навигация, фокус, удаление-добавление записей, проверка инконсистентности, сокращение числа запросов при первом открытии, стили колонок/строк, работа с колонками (растягивание/перестановка/скрытие/сортировка/запрет перестановки), нет данных, выравнивание теста, триминг, контекстные меню, количество записей, поддержка автотестов, фильтры по колонкам, like-поиск, сохранение/восстановление настроек.
Все это делали долго, наверное, полгода. Примерно ~500 чч
В итоге по трудоемкости мы вложились сильно в грид. Компания нам такую возможность дала — отказаться от DevExtreme и все переписать.
У нас в отделе прослеживается такая тенденция: берем стороннюю компоненту, понимаем что нас не устраивает ее внешний вид, поведение, работа с клавиатурой, фокусом, не хватает каких-либо возможностей. И начинаем все вылизывать, докручивать, переделывать в этой компоненте, учить ее работать с тем с чем она не умеет работать. И это не разовая работа, по ходу развития проекта появляются новые требования к уже используемым компонентам.
Это тоже сыграло роль в принятии решения.