Задать вопрос
@3ton

Как правильнее организовать архитектуру сервиса?

Есть 2 вопроса по архитектуре сервиса.
1 - выделенный(псевдовыделенный) сервис для некоторых заказчиков желающих работать в поддомене(якобы своей отдельной инсталяции)
2 - разделение нагрузки в зависимости от страны/компании/кол-ва сотрудников

Что касается первого вопроса - необходимо сделать отдельный инстанс сервиса под заказчика, либо эмулировать его выделенность, все зависит от приемуществ/безопасности подходов, но на вскидку приведу те до которых догадался(подсказали):
1.1 - использовать во всех таблицах касающихся ресурсов заказчика кроме идентификатора заказчика еще и порядковый номер строки конкретно для данного заказчика (метод по моему самый костыльный и к нагрузке не приспособленный)
1.2 - использовать для каждого заказчика свою таблицу с идентификатором в качестве постфикса для каждой таблицы (метод менее нагрузочный, но нет уверенности в безопасности такого кол-ва таблиц)
1.3 - использовать в пределах одного сервиса для каждого заказчика свою базу именно под информацию касающуюся этого заказчика (как пример используются в сервисе 20 таблиц из них 10 под хранение данных заказчика, поэтому 10 таблиц используются в базе сервиса, а под каждого заказчика заводится своя база на 10 таблиц). Есть ощущение что это будет работать быстрее предыдущих решений, но такая громоздкость очень пугает, есть ощущение оказаться под лавиной.
1.4 - использовать в пределах одного сервера с основным доменом поддомен для заказчика который имеет аналогичный основному набор таблиц в своей базе, только отличается тем что располагается в домене третьего уровня и в нем могут работать лишь сотрудники заказчика. Кажется мне наиболее верным решением, но смущает возможность столкнуться с пределом серверных ресурсов и не понимание как потом поступить.
1.5 - для каждого поддомена использовать свою отдельную виртуальную машину. В данном решении нет проблем с ресурсами, но возникает проблема с автоматическим поднятием экземпляра и поддержанием всех экземпляров в актуальном состоянии.

Возможно есть еще решения, буду рад их услышать.

Что касается второго вопроса, то есть не малая вероятность в предыдущем вопросе пойти по пути 1.5, но ко всему прочему в планах есть связать все экземпляры общим функционалом (как минимум перепиской). А это повлечет за собой необходимость связывать сообщения пользователя с одной виртуалки с пользователями другой. В данном случае вижу пока лишь 3 решения
2.1 - заводится централизованный сервер который держит всю переписку (учитывая как часто люди любят писать, мне кажется что одна таблица с перепиской очень скоро начнет тормозить)
2.2 - заводится централизованный сервер в качестве рутера который должен направлять в зависимости от какого-то фактора клиента на другой сервер где хранится связанное с ним сообщение(он может быть автором либо получателем). Этот вариант более правдоподобен, но не понятна реализация такого рутера и на сколько это будет оперативно работать.
2.3 - при отправлении сообщение хранится у отправителя, а так же копия сохраняется у получателя. Мне кажется это самое легкое решение, но опять же смущает что в определенный момент в пределах одного сервера этих сообщений станет невыносимо много, что скажется на быстродействии.
  • Вопрос задан
  • 2623 просмотра
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 4
Kwisatz
@Kwisatz
Больше web-приложений, хороших и разных
По первому: наиболее секурно все же отдельные виртуальные машины.
Однако если вопрос только в БД, при условии нормальной архитектуры самого приложения и бд скажем PostgreSQL/Oracle То я бы остановился на схемах. Причем каждый поддомен работает от своего пользователя/схемы с четко разграниченными грантами.
С управляющей схемой контактируют только системы полностью изолированные от пользователя.
Начальное копирование баз для posgre, скажем: от простого дампа основной схемы/create table like до create table of type / inherits

По второму пункту: при грамотной реализации ничего тормозить не будет, во всяком случае у меня 250млн сообщений при 2тысячах активных пользователей не тормозили абсолютно. Тут больше думать нужно над реализаций самих сообщений. Если скажем мы можем удалять свое сообщение из переписки то его копия не нужна, если не можем то табличка вида
-message_id
-message_text
-message_theme (если нужно)
-parent_id (для иерархии ответов, если нужно),
-folder_id (если нужны папочки)
-author_id
-author_name
-recipient_id
-recipient_name
-keeper_id
Решает все проблемы. На каждое сообщение создается два экземпляра и соответственно если keeper_id==author_id то это исходящее, если keeper_id==recipient_id - входящее. Имена отправителя/получателя кешируем в соответствующих полях дабы не выполнять на каждый чих лишний джоин а так же дабы не потерять адресата если вам захочется потереть пользователя из бд (что само по себе плохая идея). Определяемся нужны ли темы,папки итд и составляем индексы под наши запросы - все: радость и счастье, бабочки летают.
Ответ написан
@kvspb
ИМХО если у вас есть такие вопросы то пора открывать вакансию архитектора ПО, это самое правильное решение!
Ответ написан
gbg
@gbg
Любые ответы на любые вопросы
Вопрос очень простой - когда либо данные одного заказчика могут быть использованы у другого? Нет? Тогда чем меньше зависимостей, тем лучше.

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

Так у вас и полная изоляция будет, и снимки на ходу, и другие радости.

Инструменты для контроля за экземплярами ВМ, кластеризации и балансировки нагрузки на кластер - есть, бесплатны, и весьма удобоваримы.

Мой личный пример - Xen - Pacemaker/Heartbeat - OCFS2
Ответ написан
index0h
@index0h
PHP, Golang. https://github.com/index0h
Под 1.5 можете использовать docker. Либо системы в стиле Puppet/Chef. Многое зависит от конкретно того, что за сервисы вы делаете.

На счет 2.3 и 1.5 - будьте готовы к сложностям поддержки. На подсистему накатки обновлений ложится ОЧЕНЬ большая ответственность.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы