2014-08-28 51 views
2

我正在研究一种使用node.js + mongoose和mongodb实现多租户支持的多数据库的好方法。Mongoose为node.js中的多租户支持创建连接

我发现猫鼬支持一种名为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年9月9日 - 在软件需求

起初,我们将有大约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

始终创建和销毁连接代价昂贵 - 您是否在数据库中使用身份验证?或者只在你的应用程序中?每个租户都在单独的实例中,“db”,单独的“集合”还是......?即连接有何不同? – 2014-09-05 16:45:57

+0

嘿,thx回复。身份验证发生在应用程序级别,但它会检查mongo集合(用户)。这个想法是为每个租户都分配一个分贝(在网络上进行了一些研究后,人们说避免前缀收集,但他们没有说明为什么......)。我们还不知道租户会如何区别对待,也许还有将来的一段时间,但我希望能为不同索引做好准备。 – 2014-09-06 18:28:15

回答

6

我不建议手动创建和管理这些不同的连接。我不知道你的多租户要求的细节(租户的数量,数据库的大小,预期的数量交易等),但我认为最好是像Mongoose's useDb function这样的东西。然后Mongoose可以处理所有的连接池细节。

更新

我将探索的第一方向是设置在一个单独的节点处理每个租户。在独立的节点进程中运行租户有一些有趣的好处。从安全性角度来看(从孤立的内存)和从稳定性的角度来看(一个租户进程崩溃不会影响其他用户)。

假设您基于URL的租约,您需要在实际租户服务器前设置代理服务器。它的工作将是查看URL并根据该信息路由到正确的流程。这是一个非常简单的node http proxy设置。每个租户实例可以是完全相同的代码库,但是使用不同的配置(告诉他们使用什么mongo连接字符串)启动。

这意味着您可以将您的实际应用程序设计为不是多租户。每个进程只知道一个mongo数据库,并且不需要多租户逻辑。它还使您可以根据负载轻松分割流量。如果您出于性能原因需要拆分租户,您可以在代理级透明地完成。DNS可以保持不变,你可以移动实例在幕后的服务器。您甚至可以让代理在多个服务器之间平衡对租户的请求。

+0

我编辑了这个问题以提供更多关于需求的细节。至于useDb函数,我认为当并发请求到达服务器并更改数据库时请求仍在运行可能会非常危险。如果第一个请求还有任何操作,它可以对错误的租户进行更改。是对的吗 ?谢谢! – 2014-09-09 10:59:46

+1

useDb返回另一个数据库对象以进行操作。它不会更改现有的数据库对象,因此不会将飞行中的操作应用于错误的数据库。 – 2014-09-09 18:58:18

+0

各租户的负载是否相当一致?或者您是否期望一些租户有更高的使用/数据要求? – 2014-09-09 18:59:34