Using Java driver in multi tenancy application

216 views
Skip to first unread message

Ulf Lohbrügge

unread,
Sep 27, 2017, 4:47:47 PM9/27/17
to mongodb-user
I'm running a multi tenancy application that uses one database per tenant. My application currently serves around 2k tenants. I create one MongoClient (using Spring's MongoTemplate) per tenant and cache all MongoClients in a local HashMap.

This has some serious drawbacks as the number of threads and connections rises with every new tenant.

I stumpled upon some great slides that explain a clever approach when developing a multi tenancy application that uses MongoDB:


The author uses one Mongo instance (singleton) that acts as a connection pool for instances of MongoTemplate that are created on the fly. This is possible because MongoDB completely separates the actions of connect and authenticate. The number of threads and connection is reduced to a minimum.

Unfortunately this feature of "lazy authentication" was dropped with version 3.0 and above. An instance of MongoClient (which is the successor of the deprecated Mongo) needs the credentials for connecting to database at construction time and cannot be changed afterwards.

I'm currently running into trouble as the "instantiate one MongoClient per tenant" doesn't scale well and I'm forced to add more machines to reduce the number of threads per jvm.

Is there a better solution than "instantiate one MongoClient per tenant"? Is there an easy way to extend the Driver to support "lazy authentication" again?

Jeff Yemin

unread,
Nov 27, 2017, 3:27:13 PM11/27/17
to mongodb-user
We now explain the rationale for not supporting multiple credentials in the Q&A section of the driver authentication specification, under the question "Should a driver support multiple credentials?".

There is no easy way to extend the driver to support multi-tenancy via authentication, as it conflicts with the security properties that the driver must enforce (e.g. discourage privilege escalation) and new server features that the driver must support (e.g. sessions). 

Perhaps if you describe your use case in more detail, a way to satisfy the requirements of your application, without any changes to the driver, will become clearer.


Regards,
Jeff

jpbla...@gmail.com

unread,
Dec 1, 2017, 2:28:08 PM12/1/17
to mongodb-user
This is the exact same problem that I'm having, as asked here on StackOverflow.  Per the Javadocs for MongoClient, you're not supposed to create a MongoClient per database: "A MongoDB client with internal connection pooling. For most applications, you should have one MongoClient instance for the entire JVM."  And based on the "Should a driver support multiple credentials?" section of your link, it sounds like you're not supposed to create a single MongoClient with all the individual database credentials (though this isn't really desirable anyway, since it's not dynamic).  So what are you supposed to do, then?  Is it possible to have a single set of credentials that can be given when a MongoClient is constructed, that allow access to multiple databases?

jpbla...@gmail.com

unread,
Dec 12, 2017, 4:09:18 PM12/12/17
to mongodb-user
For anyone interested, I followed up on the question I asked at the end of my reply and found that it was possible.  I created a single user in the admin database, with a role for each database it needs to access.  Then the application just creates one MongoClient on startup, and initializes new MongoTemplates dynamically.  No additional auth is required since I'm already logged in as a user with readWrite access to the databases I'm connecting to.
Reply all
Reply to author
Forward
0 new messages