Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose create connection for multi-tenancy support in node.js

I'm researching a good way to implement multiple database for multi-tenant support using node.js + mongoose and mongodb.

I've found out that mongoose supports a method called createConnection() and I'm wondering the best practice to use that. Actually I am storing all of those connection in an array, separated by tenant. It'd be like:

var connections = [
   { tenant: 'TenantA', connection: mongoose.createConnection('tenant-a') },
   { tenant: 'TenantB', connection: mongoose.createConnection('tenant-b') }
];

Let's say the user send the tenant he will be logged in by request headers, and I get it in a very early middleware in express.

app.use(function (req, res, next) {
    req.mongoConnection = connections.find({tenant: req.get('tenant')});
});

The question is, is it OK to store those connections statically or a better move would be create that connection every time a request is made ?

Edit 2014-09-09 - More info on software requirements

At first we are going to have around 3 tenants, but our plan is to increase that number to 40 in a year or two. There are more read operations than write ones, it's basically a big data system with machine learning. It is not a freemium software. The databases are quite big because the amount of historical data, but it is not a problem to move very old data to another location (we already thought about that). We plan to shard it later if we run out of available resources on our database machine, we could also separate some tenants in different machines.

The thing that most intrigues me is that some people say it's not a good idea to have prefixed collections for multitenancy but the reasons for that are very short.

https://docs.compose.io/use-cases/multi-tenant.html

http://themongodba.wordpress.com/2014/04/20/building-fast-scalable-multi-tenant-apps-with-mongodb/

like image 757
Danillo Corvalan Avatar asked Aug 28 '14 14:08

Danillo Corvalan


1 Answers

I would not recommend manually creating and managing those separate connections. I don't know the details of your multi-tenant requirements (number of tenants, size of databases, expected number transactions, etc), but I think it would be better to go with something like Mongoose's useDb function. Then Mongoose can handle all the connection pool details.

update

The first direction I would explore is to setup each tenant on a separate node process. There are some interesting benefits to running your tenants in separate node processes. It makes sense from a security standpoint (isolated memory) and from a stability standpoint (one tenant process crash doesn't effect others).

Assuming you're basing the tenancy off of the URL, you would setup a proxy server in front of the actual tenant servers. It's job would be to look at the URL and route to the correct process based on that information. This is a very straightforward node http proxy setup. Each tenant instance could be the exact same code base, but launched with a different config (which tells them what mongo connection string to use).

This means you're able to design your actual application as if it wasn't multi-tenant. Each process only knows about one mongo database, and there is no multi-tenant logic necessary. It also enables you to easily split up traffic later based on load. If you need split up the tenants for performance reasons, you can do it transparently at the proxy level. The DNS can all stay the same, and you can just move the server that the instances are on behind the scenes. You can even have the proxy balance the requests for a tenant between multiple servers.

like image 176
Timothy Strimple Avatar answered Nov 15 '22 12:11

Timothy Strimple