Shared Instances Across Tenants
A more optimal way of implementing a multi-tenant cloud (SaaS or PaaS) solution is to deploy shared instances of servers across multiple tenants. This is where the cloud starts to pay off. With this approach, compute and storage resources are shared across multiple tenants, resulting in a lower cost of service for each tenant.
With this approach, the following levels of sharing can be implemented to further reduce the cost of the service:
- Instance sharing: Instance sharing can be done either at the database server level only or at both the application and database server levels. Of course, more sharing means more savings, which you can pass on to customers with lower service prices. But more sharing also requires more upfront thought about the architecture and design of the service, because any problem with the shared instance will affect multiple tenants. This higher upfront investment can have a huge long-term payoff though by reducing the operational cost (and hence total cost of ownership) of the service.
- Database schema sharing: If instance sharing is implemented at the database level, within the same database server instance either a separate database user schema can be deployed for each tenant or all tenants can share a common database user schema. A common database schema is more cost effective than instance sharing, but it can be challenging to implement and optimize. Handling custom extensions for each tenant can make this even harder to implement.
One way to deal with this is to drive functionality based on metadata. To support tenant-specific extensions to processes and policies, each tenant can inherit the common metadata and define its own metadata on top of that. This is how Salesforce.com is designed. Database partitioning strategies can be implemented for better performance. Data is usually partitioned based on customer ID (Tenant ID) to keep all the data for a given customer in the same partition for performance reasons. A certain number of predetermined tenants live in each partition. The extent to which tenant-specific extensions need to be supported depends on the nature of the service as mentioned earlier (e.g. email vs. sales force automation).
- Application code sharing: If instance sharing is implemented at the application server level, then within the same application server instance either separate code modules can be deployed for each tenant or all tenants can share the same code module deployment (e.g. .war file). Again, more sharing means more savings, but the operational issues have to considered and a lot of thought has to go into the architecture and design of the shared application. All the rules should be externalized so that tenant-specific extensions to processes and policies can be incorporated in the shared codebase.
Application partitioning strategies can be implemented to improve performance and scalability of shared applications. Multiple partitions can be created to support large sets of tenants. Requests can be routed to the correct partition based on tenant ID and/or other predetermined criteria.
There are multiple ways to implement multi-tenancy. Which one you choose depends on the nature of the service being implemented. However, it is very important to spend the necessary time upfront during the architecture phase to determine your current and future multi-tenancy needs and to come up with the best design. After the approach has been decided and implemented, it can be extremely difficult and costly to change, much like converting a four-unit apartment complex into a multiplex would be almost impossible without starting from scratch.
In the next installment of the implementing a multi-tenant cloud architecture
series, I drill down into the multi-tenancy approaches
for each of the three application tiers.