We started working on our multitenancy philosophy at the early stages of designing cloud service support in 1C:Enterprise. This was several years ago, and since then our concept of multitenancy keeps expanding steadily. We constantly discover new aspects: pros and cons, complexities and peculiarities.
Some developers have a very basic understanding of multitenancy: "To store multiple companies’ data in a single database, we’ll just add the Company ID column to all tables and then filter them by this column." That’s where we started, too. However, we quickly realized that it’s just one island (with many mysteries of its own) in an entire archipelago.
We’ll describe the basic idea of multitenancy using a visual example. A simple application is a house built for a single family, which uses the house infrastructure: walls, roof, water, power, and so on. A multitenant application is an apartment block where all families share the house infrastructure, which is implemented at the house level.
Is multitenancy good? Opinions vary. There is no such thing as ultimate good or evil, you always have to weigh the pros and cons for your specific tasks. However, it is out of scope of this article.
In simple terms, the goal of multitenancy is cutting the costs by distributing infrastructure costs between the tenants. It is similar to cutting costs by selling out-of-box solutions (which, of course, might need some customization) instead of writing a custom solution for each customer. Multitenancy is aimed at sharing maintenance costs, while out-of-box solutions are aimed at cutting development costs.
Note that multitenancy does not necessarily imply selling a product to multiple companies. Corporations and public institutions can use multitenant architecture to automate own branches and subsidiaries.
Multitenancy is more than just a set of data storage rules. It is an entire application model affecting a lot of architectural, deployment, and maintenance aspects.
The most complex and interesting aspect of multitenancy is its dual nature. One part of application functionality affects individual data areas (apartments), treating each area as if it were the only one available. The other part applies to the entire house, affecting all tenants. Still, this part must be aware of individual apartments in order to support access granularity and security.
1C:Enterprise implements the multitenancy model at multiple levels, which include the platform itself, 1cFresh application development and publishing technologies, and 1C:Subsystems Library.
Each of these levels is important and necessary for building an apartment block. Why several levels and not just the platform? Because some of the algorithms might require modification at the deployment stage. Choosing a level for implementing another aspect of multitenancy is always a complex task.
Clearly, the basics of multitenancy support (for example, data separation) must be implemented in the platform. Still, there is much more to it. The multitenancy model touches a significant part of platform mechanisms, causing their refactoring or even redesign.
The mechanisms implemented at the platform level provide a basis for development of multitenant applications. However, to run and maintain the applications, you need appropriate management tools. These are implemented in 1cFresh and at the unified business-logic layer of 1C:Subsystems Library. Like an apartment block infrastructure provides its tenants with everything they need, 1cFresh technologies provide multitenant applications with everything they need. To provide the applications with the capability to interact with the infrastructure (without any big customizations), 1C:Subsystems Library provides "sockets" that can be easily built into the applications.
With the development of multitenancy and cloud technology support, we expand the list of mechanisms involved in this architecture. For example, the application maintainer roles change over time. As responsibility level of application maintenance staff increases, they require more powerful management tools. It is because application users (apartment dwellers) trust their service provider, and this is the reason behind the implementation of security profiles in 1C:Enterprise 8.3. Service provider administrators can use security profiles to apply security restrictions (effectively isolating each tenant in their own "sandbox").
The application management architecture (the functionality implemented in 1cFresh technologies and 1C:Subsystems Library) is also interesting. Compared to the regular deployment model, this architecture implies stricter requirements to deployment automation processes. There are dozens of such processes: creation of data areas ("apartments"), application updates, updates of regulatory data, backup creation, and more. Of course, this also increases the requirements to service availability and reliability. For example, we implemented the technology for asynchronous calls with guaranteed delivery to ensure reliable interaction between applications and management system components.
Data and process sharing is also tricky, though it might look easy at first glance. The hardest part is maintaining the balance between data and process centralization and decentralization. On the one hand, centralization reduces costs (in terms of disk space, CPU resources, and administrator efforts). On the other hand, it restricts tenant freedom. This is one of the aspects of the "dual nature" that we mentioned before: a developer must think about the application both in a narrow sense (a service for a single "apartment") and in a broad sense (a service for all the tenants).
For example, developers might want to share a single instance of regulatory data between all tenants. This simplifies the storage and update of this data. However, a tenant might want to introduce some changes to this data. Strangely, they often want to alter even regulatory and legislation data provided by government bodies. So, to share or not to share? Sharing the data and having the option to substitute custom data for specific users is tempting, however, this adds complexity to the implementation. Still, we’re looking into this.
Another example features the design of scheduled processes. One can make them data area-specific; however, such granularity increases the overall system load. To reduce the load, you need to implement shared processes, which require much more attention.
And of course, the question asks itself: how can application developers add multitenancy to their applications? We are doing our best to solve technological and infrastructure-related issues at the technology level, leaving only business logic-related tasks to application developers. Still, developers must understand the multitenancy model and they still need to invest some effort into multitenancy support. This is because no technology can provide a universal, semantics-independent solution. For example, there is no universal algorithm for deciding which data should be shared. Still, we do our best to simplify the development of multitenant applications and some of them have already hit the market.
It is important to note that we provide a hybrid multitenancy model where a single application can run in both regular and multitenant modes. This is a complex task that is well worth a separate article.