Multi-Tenant Seam + JPA Application
I work on an existing Seam 2.2.0 + JPA (Hibernate 3.3.1) application that needs to be converted to a 'single database per client' environment where each database schema is the same. The application runs on Glassfish, uses IceFaces, and has several pages that utilize Conversations. It also uses a single EJB for authentication. Unfortunately, the decision to split clients off into their own databases is outside of my control.
As a proof of concept, I have already made the application aware of multiple databases by moving the management of EntityManagerFactory(ies) and DataSource(s) into the application using Spring JPA abstractions, resource local transactions, and ThreadLocal for context information. For example, each time a user logs in a new EntityManagerFactory is initialized using a new DataSource that communicates with their database if it has not already been initialized. This is working well in a test environment with a handful of databases.
My question is, will this approach scale to hundreds of databases? I expect to add application servers to a load balancer to handle additional load, but will the overhead of the Hibernate/JPA fi开发者_运维技巧rst-level cache and/or Seam context management (a.k.a., memory consumption) require significantly more servers to scale compared to a typical load balanced application? If so, can this be mitigated by allocating servers with lots of RAM and/or a large distributed cache?
Any insight would be greatly appreciated.
I worked on an application with this approach and I what I can point out is:
- Datasource and EntityManagerFactory management is the hard part. However it seems you did this already in the test environment. Double check if you did things right in respect of the Seam Managed Entity Manager.
- Your application won't scale well on hundreds of databases because you have a linear increase of memory consumption for each database. In fact, for each database you are going to have different instances of
EntityManagerFactory
(HibernateSessionFactory
) each requiring a considerable amount of Ram. - Beware of possible issues if you configure Hibernate second level cache. Since all SessionFactories are created from the same data model the cache region names may collide. I used
hibernate.cache.region_prefix
configuration parameter to make these names uniques among the various instances using the database id as the cache prefix.
精彩评论