Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Multi-tenancy in Hibernate 
V
    Опции темы
Samotnik
Дата 10.5.2011, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Привет.  smile 
Есть задача, реализовать Multi-tenancy в приложении, а точнее создать архитектуру БД. Если кто-то не знаком с этим понятием объясню на примере: главная сущность tenant - по сути пользователь, либо группа, остальные сущности вертятся вокруг нее, например сущности: Машина, Квартира, Женщина. 
Необходимо: если залогинился тенант А - показывать ему только его машины, квартиры, женщин, если тенант Б - только его женщин, машины квартиры и т.д.  по аналогии smile
Погуглив, кое - что нашел
Но все как бы в теории + единого метода так никто и не предложил, то памяти много отжирает,то с кэшем второго уровня проблемы.
Есть 3 основных метода:
  • Separate database instances - This approach gives each tenant their own physical database instance.
  • Separate schemas - This approach uses the same physical database instance for all the tenants, but each gets its own schema (or catalog) within that instance.
  • Partitioning - This approach uses the same database instance and same schema. In other words a single table holds the data for every tenant. The tenants are "partitioned" by some form of discriminator value.
третий в принципе понятен, но не ясно его преимущество. Он гласит, что в каждой сущности, нужно иметь поле тенанта, далее накидываем hibernate фильтр, где участвует tenant_id - но при создании новой сессии нужно этот фильтр включать и сетить проперти, я в упор не понимаю чем это лучше, без никакого фильтра просто подставлять tenant_id в запрос ?
Первый и второй - тоже не ясны. Там предлагают создавать для каждого тенанта свою SessionFactory. Но ведь SessionFactory - это логическая работа с БД, а как физически будут записи храниться в одних и тех же сущностях ? Плюс вопрос, если будет 100 тенантов, то придется создавать 100 SessionFactory ? smile

В общем, если кто знает еще какие- нибудь способы, подскажите пожалуйста, либо если кто-нибудь применял или разбирается в тех, что я выложил, объясните пожалуйста преимущества их.
 smile 


Это сообщение отредактировал(а) Samotnik - 10.5.2011, 22:36
PM MAIL   Вверх
Старовъръ
Дата 10.5.2011, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.5.2008

Репутация: 1
Всего: 10



Ну фильтры в Хибе не на SessionFactory устанавливаются, а на Session. 
Вообще, глянь на Spring Security ACL или на другие реализации ACL, может тебе это поможет. 
По поводу пунктов - лично для меня первые два просто ересь smile
PM MAIL WWW   Вверх
Samotnik
Дата 10.5.2011, 23:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Цитата(Старовъръ @  10.5.2011,  23:28 Найти цитируемый пост)
Ну фильтры в Хибе не на SessionFactory устанавливаются, а на Session. 

знаю smile
так в чем преимущество фильтра перед тем, чтобы просто в запрос вставлять доп параметр - tenant_id ?
PM MAIL   Вверх
dobrolub
Дата 11.5.2011, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 385
Регистрация: 18.12.2009
Где: Vancouver, Canada

Репутация: 4
Всего: 16



С фильтром меньше кода...

В javaee 7 народ фокусируется на multi-tenancy и cloud, поэтому наверно подход #3 более интересен.

Это сообщение отредактировал(а) dobrolub - 11.5.2011, 00:09
PM   Вверх
carper
Дата 11.5.2011, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 2.3.2005

Репутация: 2
Всего: 8



Цитата(Samotnik @  10.5.2011,  23:34 Найти цитируемый пост)
так в чем преимущество фильтра перед тем, чтобы просто в запрос вставлять доп параметр - tenant_id ? 


Ну, в том виде в каком обычно это приводят в примерах особого преимущества не просматривается, в реальности же можно переопределить метод openSession() и осуществлять централизованное управление безопасностью, возвращая сессию с уже установленными фильтрами.


P.S.
IMHO ваш пример, не очень хорош, т.к. прежде чем выносить управление безопасностью за пределы собственно базы данных надо очень и очень подумать, а стоит ли создавать столь лакомый уязвимый пункт, как незащищенная СУБД, полагающаяся полностью на то, что доступ к ней будет только из вашего приложения.
Не говоря уж о том, что понятие представления (разумеется, это только небольшой кусочек системы безопасности) существует практически в любой СУБД, легко тюнится админом СУБД (в отличие от непредсказуемых запросов Hibernate) и очень удобно в использовании в том же Hibernate.

Между прочим, и метод 2, при передаче заботы о безопасности на уровень СУБД, тогда будет выглядеть отнюдь не ересью, а вполне разумным подходом.



PM MAIL   Вверх
Samotnik
Дата 11.5.2011, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Цитата(carper @  11.5.2011,  08:38 Найти цитируемый пост)
Между прочим, и метод 2, при передаче заботы о безопасности на уровень СУБД, тогда будет выглядеть отнюдь не ересью, а вполне разумным подходом.

не понимаю выгоду, если будет 100 тенантов, то ведь и будет 100 схем, а сто схем, это стопроцентные проблемы с кэшем второго уровня, памятью и прочим...

Цитата(carper @  11.5.2011,  08:38 Найти цитируемый пост)
IMHO ваш пример, не очень хорош, т.к. прежде чем выносить управление безопасностью за пределы собственно базы данных надо очень и очень подумать, а стоит ли создавать столь лакомый уязвимый пункт, как незащищенная СУБД, полагающаяся полностью на то, что доступ к ней будет только из вашего приложения.
Не говоря уж о том, что понятие представления (разумеется, это только небольшой кусочек системы безопасности) существует практически в любой СУБД, легко тюнится админом СУБД (в отличие от непредсказуемых запросов Hibernate) и очень удобно в использовании в том же Hibernate.

Вот это тоже не ясно. Вы предлагаете всю схему управления тенантами вынести на уровень БД ?
PM MAIL   Вверх
MisterCleric
Дата 11.5.2011, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Привет.
У меня такая вещь реализована через розграничение прав доступа к данным на уровне БД.
При каждом request я делаю insert в некую сессионную временную таблицу информации о залогиненном пользователе.
А данные вычитываю с помощью View, где уже и накладывается рестрикшн на данные, которые возвращать.
Я так думаю, решение, которое здесь представлено вполне годится.
Могу смело сказать, что мое решение соответсвует данным инструкциям. Разве что у меня нет привязки к конкртеному фильтру, так как на уровне представлений я могу какие-угодно понавешивать фильтрации в зависимости от прав пользователя, его групп, организаций, в которые он входит...


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 11.5.2011, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



MisterCleric, спасибо, почитал коменты, что-то понравилось, что-то нет. Но вопрос так и остался открытым, использовать Partitioning хорошо или плохо ? smile
PM MAIL   Вверх
MisterCleric
Дата 11.5.2011, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Цитата

Но вопрос так и остался открытым, использовать Partitioning хорошо или плохо ?

А зачем? ведь 100 - это не миллион...
Да и не спасет оно тебя.
Потому как "партиции" изначально предопределяются на уровне архитектуры БД. Т.е. "секьюрити" на них не постоишь.
Ты попробуй сначала с простыми индексами, а потом, когда набется несколько миллионов записей, то и будешь и уже делить. 


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 11.5.2011, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



MisterCleric, ничего не понял, можешь по-понятнее немного объяснить smile
PM MAIL   Вверх
MisterCleric
Дата 11.5.2011, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Цитата

можешь по-понятнее немного объяснить


Давай по очереди: что именно не понятно?

Если вообще, то партиции нужны при большом количестве данных, а так вообще обходятся обычными индексами по внешним ключам.
Если по поводу того, как они создаются, то тогда это к твоему вендору СУБД.



--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
carper
Дата 11.5.2011, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 2.3.2005

Репутация: 2
Всего: 8



Цитата(Samotnik @  11.5.2011,  14:22 Найти цитируемый пост)
не понимаю выгоду, если будет 100 тенантов, то ведь и будет 100 схем, а сто схем, это стопроцентные проблемы с кэшем второго уровня, памятью и прочим...


Я разве сказал, что партиции надо пихать везде?

Просто само их применение в определенных случаях обретает смысл.

И не надо для 1000 схем создавать 1000 партиций, вы ведь безопасность настраивать не будете для всех 1000 пользователей по отдельности, а будете действовать через роли.
Вот тут и можно эффективно выделить несколько групп ролей и осуществить партиционирование уже по ним.

И вообще, не видя конкретной архитектуры и нагрузки на базу странно рассуждать о партиционировании более конкретно. smile


Цитата(Samotnik @  11.5.2011,  14:22 Найти цитируемый пост)
Вы предлагаете всю схему управления тенантами вынести на уровень БД ? 


1. Только тесно завязанную на безопасность (имеется в виду не только защита от злоумышленников, но и логическая целостность критически важных данных).

2. Широко использовать view и, если у вас нет требования к независимости от вендера, другие возможности СУБД, предназначенные для таких вещей, например Oracle Label Security.

3. Остальное храните себе на ApplicationServer и используйте хоть запросы по id, хоть фильтры, когда последние будут полезны я вроде как уже написал.


И вообще, не надо на сервере приложений пытаться моделировать тригеры, представления, foreign key, генераторы id - почти во всех, даже бесплатных базах, все это есть, работает эффективней и гораздо более отлажено и протестировано, позволяет задействовать админов СУБД, более профессионально решающих некоторые вопросы чем разработчики под JAVA.

Уходя от вышеизложенного вы получите лишние 0,5% доп. свободы от вендора и лишние 50% гемороя по изобретению велосипеда и разыскивая знатоков Hibernate там, где даже JAVA знать не надо.

PM MAIL   Вверх
Samotnik
Дата 11.5.2011, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Цитата(MisterCleric @  11.5.2011,  16:32 Найти цитируемый пост)
Давай по очереди: что именно не понятно?

отвечу вопросом на вопрос.
такой способ считается нормальным или нет ?
Т.е.
создать package-info.java в пакете с entity классами, там, в нём:
Код

@FilterDefs({
    @FilterDef(name = "tenantFilter", parameters = {@ParamDef(name = "tenant_id", type = "long" )}, defaultCondition = ":tenant_id = tenant_id")
})
package my.project.entities;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.FilterDefs;
import org.hibernate.annotations.ParamDef;

Затем, в каждый entity класс добавить поле tenant_id (из entity класса Tenant, по связи @ManyToOne), и в каждом классе применять фильтр:
Код

@Filter(name = "deletedFilter")
public class Test { ....}

ну и в сессию естессно добавить 
Код

session.enableFilter("tenantFilter").setParameter("tenant_id", id);


Это сообщение отредактировал(а) Samotnik - 11.5.2011, 17:37
PM MAIL   Вверх
MisterCleric
Дата 11.5.2011, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Почему нельзя это все вынести на уровень представлений в БД?
Будет меньше компилированного кода на java.
А не дай бог придется к каким-то сущностям добавить еще фильтров?

Ну, в общем, дело мастера боится: раз такой способ есть, значит он имеет право на жизнь.
Не бойся и эксперементируй


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 11.5.2011, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Цитата(MisterCleric @  11.5.2011,  17:40 Найти цитируемый пост)
Почему нельзя это все вынести на уровень представлений в БД?

не понимаю, о чем речь и как это сделать ? smile
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.1114 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.