How to design a multi-tenant node.js application?
Asked Answered
A

2

7

Currently I am facing a technological decision to be made and personally am not able to find the solution myself.

I am currently in progress to develop a multiple-tenant database.

The structure would be the following:

  • There is one core database which saves data and relations about specific tenants
  • There are multiple tenant database instances(from a query in the core database, it is determined which tenant id I should be connecting to)
  • Each tenant is on a separate database instance(on a separate server)
  • Each tenant has specific data which should not be accessible by none of other tenants
  • Each database would preferably be in mySQL(but if there are better options, I am open to suggestions)
  • Backend is written in koa framework
  • The database models are different in the core database and tenant databases
  • Each tenant database's largest table could be around 1 mil records(without auditing)
  • Optimistically the amount of tenants could grow up to 50

Additional data about the project:

  • All of project's data is available for the owner
  • Each client will have data available for their own tenant
  • Each tenant will have their own website
  • Database structure remains the same for each tenant
  • Project is mainly a logistics service, which's data is segregated for each different region

The question:

Is this the correct approach to design a multi-tenant architecture or should there be a redesign in the architecture?

If multi-tenant with multiple servers are possible - is there a preferable tool/technology stack that should be done? (Would love to know more specifically about this)

It would be preferred to use an ORM. I am currently trying to use Sequelize but i am facing problems already at early stage(Multiple databases can't share the same models, management of multiple connections).

The ideal goal would be the possibility of adding additional tenants without much additional configuration.

EDIT: - The databases would be currently hosted in Azure, but we'd prefer the option that they can be migrated away if it becomes a requirement

Amabil answered 13/4, 2018 at 7:55 Comment(3)
At the minute your question isn't really answerable because there isn't enough context on the type of app your building. The design decisions behind multi-tenancy are driven by various factors e.g. expected no. of tenants, volume of data expected, flexibility of change per tenant etc.Linneman
I will try to add some more information to try to clarify. Thanks either way :)Amabil
medium.com/@mohamedsameer72/…Paresh
D
6

Exists some ways to architect a data structure in a multi tenant architecture. It's so hard to say what is the better choice, but I will try to help you with my little knowledge.

First Options:

Segregate your database in distributed servers, for example each tenancy has your own data base server totally isolated.

It could be good because we have a lot of security with tenancy data, we can ensure that other tenancy never see the other tenancy data.

I see some problems in this case, thinking about cost we can increase a lot it because we need a machine to each client and perhaps software license, depends what is your environment. Thinking about devops, we will need a complex strategy to create and deploy a new instance for every new tenancy.

Second Options

Separate Data Bases, we have one server where we create separated databases to each tenancy.

This is often used if you need to provide isolation for each customer, because we can associate different logins, permissions and so on to each database.

Some other cons: A different connection pool is required per database, updates must be replicated across all the databases, there is no resource sharing (unless using Elastic Database Pools) and you need multiple backup strategies across all the databases, and a complex devops strategy to deploy and create new tenancies.

Third Option:

Separate Schemas, It's a good strategy to implement a multi-tenancy architecture, we can share some resources since everything is inside the same database, but the schemas used are different, having a separate schema for each tenant. That allows you to even customize a specific tenant without affecting others. And you save costs by only paying for one database.

Some of the cons: You need to replicate all the database objects in every schema, so the number of objects can increase indefinitely, updates must be replicated across all the schemas, the connection pool for the database must maintain a different connection per tenant (or set of credentials), a different user is required per tenant (which is stored at server level) and you have to backup that user independently.

Fourth Option

Row Isolation.

Everything is shared in this options, server, database and schema, All data for the tenants are in the same tables in the same database. The only way they are differentiated is based on a TenantId or some other column that exists on the table level.

Other good point is that you will not need a devops complex strategy, and if you are using SQL Server, I know that, there exists a resource called Row Level Security to you get only the data that logged user has permission.

But in this case if you have thousands of users who will be hitting the database at the same time you will need some approach for a good scalability.

So you need to think about your case and how your system will be growing up, to choose the better option.

Dansby answered 13/4, 2018 at 8:23 Comment(2)
And there are a few more options than this, the question isn't really answerable because there is pretty much zero context on what type of app the user is building.Linneman
@Linneman yes we can't help our friend without more context, but I can try let some options to clarify your his mindDansby
D
0

It seems quite fine for me.

Where I see a bottleneck is having every tenant on a separate DB server or DB instance. It would mean that you need to hold a separate connection pool for every tenant or to create a new connection for every request depending on the tenant. Try using any concept where you can have one DB connection for all the tenants (namespaces, schemas or just prefixing tenant table names with some tenant-specific prefix)

But if you need to have the tenants DBs separate eg. because of different backup policies, resource limits etc. you can't do this and will have to manage separate connection pool for every tenant. It also depends on how many tenants will you have. Tens, thousands?

I would also suggest you to cache the tenant->DB mapping somewhere in the app instead of querying it every time from the core database.

Dalpe answered 13/4, 2018 at 8:21 Comment(1)
At start it would be about 2/3 and could grow up to 50Amabil

© 2022 - 2024 — McMap. All rights reserved.