multi-tenant vs multi-instance design advice

786 views
Skip to first unread message

Steve Odom

unread,
Oct 21, 2011, 7:36:02 AM10/21/11
to mongodb-user
Our app will have lots of business users. We're worried about co-
mingling of data as well as different vastly different data sizes and
loads between these customers.

Currently, we have all the data in one collection, identified by a
customer_id. Everything is co-mingled.

To get around the co-mingling, we could give each customer a unique
collection but we're a little worried about reaching the maximum
number of collections this way, as well as being not being able to
address the different scalability requirements of each customer.

We're considering a multi-instance approach where each customer would
get their own database. I should indicate too we're using MongoHQ at
Heroku. What we're trying to figure out is whether this would be 1 app
with lots of potential connections to multiple databases. If so, how
do we manage all of those connections? Would we run into upper limits
as to the number of connections?

Any other suggestions/pitfalls we should consider?

Thanks,

Steve

Octavian Florescu

unread,
Oct 21, 2011, 6:43:40 PM10/21/11
to mongod...@googlegroups.com
We are facing similar issues (not in production yet, still evaluating mongodb as a possible solution).
The approach I took so far is to design such way that we can have customer-per-DB, customer-per-collection, or a combination. No conclusive results yet which approach would be better (same concern as you about number of collections, etc, we are quite granular, lots of collections per customer).

As we will probably end up with a multi-tenant system, and potentially being under contractual obligations regarding co-mingling of data, I built encryption (and compression) on top of a chunking (to address the user object size limitation, see below) streaming API (Java driver) into mongodb. We are using AES 128b by default, and the performance impact is not bad at all (if you have also compression, do that first and then encryption,or it will render the compression useless and just use CPU time for nothing :o). In the extreme case where a customer wants physical data separation, we would probably use different mongodb clusters. As far as I know, the Java driver pools the connections per-DB.

Cheers,

PS the comments from my code (need to check these in 2.0) :
// Mongodb (as of 1.8.3) has a user object size limitation of 16M (builder.h defines it as
// BSONObjMaxUserSize = 16*1024*1024). BUT it seems that size can change, based on who is
// master, replica sets dynamics, etc, so we cannot interrogate Mongo to get that size and use it
// to trigger chunking.
public static final int DEF_CHUNK_SIZE = 15 * 1024 * 1024; // 15M



--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.




--


Octavian Florescu
oflo...@gmail.com

Martin Wawrusch

unread,
Oct 22, 2011, 1:47:36 AM10/22/11
to mongod...@googlegroups.com
Just some thoughts:

You will want to have both, multi tenant and multi instance. You need multi instance for demo and freemium purposes, it is the only sane and financially viable way to do this when you use cloud hosted dbs (and mongohq.com is a great choice, we use it for a year now with great success). Even if you do not plan to go freemium yet you need to be prepared for it in case a competitor does.

Implementing multi tenant ist quite easy too. I have written an API client for mongohq that lets you create databases (https://github.com/scottyapp/ruby-mongohq), It supports the beta version of the mongohq API but will be updated next week to support the current version they released a couple of days ago. If you use node.js, then a version for this is also coming.

We discussed multiple scenarios either on this or the mongoid list. Personally I am not a big fan of mingeling like it would have been done in SQL (with say a customer key), instead I would use a scheme like customername.mycollection and dynamically change this based on request type. 

For multiple physical databases I would create multiple instances of the app server as well. You would have one master database that manages all the info and assign domain names.

so you would map
yourapp.com --> server 0 with your main app control db
xxx.yourapp.com -> server 1 with db 1 collection name yxx.collection
yyy.yourapp.com -> server 1 with db 1 collection name yyy.collection
zzz.yourapp.com -> server 2 with db 2 collection name zzz.collection

This is rather easy to achieve even in a full cloud scenario, some thought needs to be put into inexpensive SSL and making this seamless. However you can always start with single database/multiple collections and add multi server later on.

Martin Wawrusch

unread,
Oct 22, 2011, 2:01:02 AM10/22/11
to mongod...@googlegroups.com
Seems I got coffee withdrawal syndrom and mixed up instance and tenant a couple of times. It should be obvious how to read it though. Sorry for the mixup.

Tony Hannan

unread,
Oct 24, 2011, 4:04:25 PM10/24/11
to mongod...@googlegroups.com
What is the data model? Documents of the same type belong together in the same collection. You cn shard the collection if it gets big. If you are talking about hosting customers each with their own data model, then have a db per customer.

Steve Odom

unread,
Oct 24, 2011, 5:06:39 PM10/24/11
to mongodb-user
The data model is the same for each customer.

Tony, what do you see as the major arguments *against* having a db per
customer that have similar data models?

The arguments *for*, as I see them, are no data mingling and the
option of dealing with small/large customers differently.

Is it that the complexities of managing lots of databases outweighs
these benefits?

Steve

Tony Hannan

unread,
Oct 24, 2011, 5:20:40 PM10/24/11
to mongod...@googlegroups.com
The arguments against a db per customer is: Mongo allocates a separate file(s) for each db, and each file has unused preallocated space.

Steve Odom

unread,
Oct 24, 2011, 9:35:44 PM10/24/11
to mongodb-user
Awesome. Thanks guys.
Reply all
Reply to author
Forward
0 new messages