我正在研究使用node.js + mongoose和mongodb为多租户支持实现多个数据库的好方法。
我发现mongoose支持一个名为createConnection()
的方法,我想知道使用它的最佳实践。实际上我将所有这些连接存储在一个由租户分隔的数组中。它就像是:
var connections = [
{ tenant: 'TenantA', connection: mongoose.createConnection('tenant-a') },
{ tenant: 'TenantB', connection: mongoose.createConnection('tenant-b') }
];
假设用户通过请求标头发送他将要登录的租户,我会在快速的中间件中获取它。
app.use(function (req, res, next) {
req.mongoConnection = connections.find({tenant: req.get('tenant')});
});
问题是,是否可以静态存储这些连接,或者每次发出请求时更好的移动都会创建该连接?
编辑2014-09-09 - 有关软件要求的更多信息
起初我们将有大约3个租户,但我们的计划是在一两年内将这个数字增加到40个。读取操作比写入操作多,它基本上是一个带有机器学习的大数据系统。它不是免费增值软件。数据库非常大,因为历史数据量很大,但将非常旧的数据移动到另一个位置并不是问题(我们已经考虑过了)。如果我们的数据库机器上的可用资源不足,我们计划稍后对它进行分片,我们也可以将不同机器中的一些租户分开。
最引起我兴趣的是,有些人说为多租户设置前缀集合并不是一个好主意,但其原因很短。
https://docs.compose.io/use-cases/multi-tenant.html
http://themongodba.wordpress.com/2014/04/20/building-fast-scalable-multi-tenant-apps-with-mongodb/
答案 0 :(得分:8)
我不建议手动创建和管理这些单独的连接。我不知道您的多租户要求的详细信息(租户数量,数据库大小,预期数量交易等),但我认为最好使用Mongoose's useDb function之类的东西。然后,Mongoose可以处理所有连接池细节。
我要探索的第一个方向是在单独的节点进程上设置每个租户。在单独的节点进程中运行租户有一些有趣的好处。从安全角度(隔离内存)和稳定性角度来看,这是有道理的(一个租户流程崩溃不会影响其他人)。
假设您将租约基于URL,您将在实际租户服务器前设置代理服务器。它的工作是查看URL并根据该信息路由到正确的进程。这是一个非常简单的node http proxy设置。每个租户实例可以是完全相同的代码库,但是使用不同的配置启动(告诉他们要使用的mongo连接字符串)。
这意味着您可以将实际应用程序设计为不是多租户。每个进程只知道一个mongo数据库,并且不需要多租户逻辑。它还使您可以根据负载轻松分割流量。如果出于性能原因需要拆分租户,可以在代理级别透明地执行。 DNS可以保持不变,您可以在后台移动实例所在的服务器。您甚至可以让代理平衡多个服务器之间的租户请求。