如何设计一个多租户的node.js应用程序?

alo*_*ins 5 database orm multi-tenant node.js koa

目前,我正面临一项技术决策,个人无法亲自找到解决方案。

我目前正在开发多租户数据库。

结构如下:

  • 有一个核心数据库可以保存有关特定租户的数据和关系
  • 有多个租户数据库实例(根据核心数据库中的查询,确定我应该连接到哪个租户ID)
  • 每个租户都在单独的数据库实例上(在单独的服务器上)
  • 每个租户都有特定的数据,其他租户都不应该访问这些数据
  • 每个数据库最好都位于mySQL中(但是如果有更好的选择,我愿意提出建议)
  • 后端是用koa框架编写的
  • 核心数据库和租户数据库中的数据库模型不同
  • 每个租户数据库的最大表可能有大约100万条记录(未经审核)
  • 乐观地,租户数量可能会增长到50

有关项目的其他数据:

  • 项目的所有数据可供所有者使用
  • 每个客户将拥有可用于其自己租户的数据
  • 每个租户都有自己的网站
  • 每个租户的数据库结构保持不变
  • 项目主要是物流服务,其数据是针对每个不同区域进行隔离的

问题:

这是设计多租户架构的正确方法还是应该在架构中进行重新设计?

如果可以使用多服务器的多租户-是否应该有一个更好的工具/技术堆栈?(想更具体地了解这一点

最好使用ORM。我目前正在尝试使用Sequelize,但是在初期我已经面临问题(多个数据库无法共享相同的模型,无法管理多个连接)。

理想的目标是无需过多配置即可添加其他租户的可能性。

编辑:-数据库当前将托管在Azure中,但是我们希望可以选择将它们迁移到需要的位置

Nic*_*shi 5

存在一些在多租户体系结构中构建数据结构的方法。很难说什么是更好的选择,但是我将以我的一点知识来帮助您。

第一选择:

将您的数据库隔离在分布式服务器中,例如,每个租户将您自己的数据库服务器完全隔离。

可能会很好,因为我们对租用数据有很多安全保护,我们可以确保其他租用永不看到其他租用数据。

在这种情况下,我会看到一些问题,考虑成本时,我们可能会增加很多成本,因为我们需要为每个客户端提供一台机器,也许还有软件许可,这取决于您的环境。考虑到开发人员,我们将需要一个复杂的策略来为每个新租户创建和部署新实例。

第二选择

在单独的数据库中,我们有一台服务器,在其中为每个租户创建单独的数据库。

如果您需要为每个客户提供隔离,则通常使用此方法,因为我们可以将不同的登录名,权限等关联到每个数据库。

其他一些缺点:每个数据库需要一个不同的连接池,更新必须在所有数据库中复制,没有资源共享(除非使用弹性数据库池),并且您需要在所有数据库中使用多个备份策略以及一个复杂的devops策略部署和创建新的租约。

第三种选择:

单独的模式,这是实现多租户架构的好策略,由于所有内容都在同一数据库中,因此我们可以共享一些资源,但是使用的模式不同,每个租户都有单独的模式。这样,您甚至可以自定义特定的租户,而不会影响其他租户。而且,您只需支付一个数据库即可节省成本。

缺点:您需要在每个架构中复制所有数据库对象,因此对象的数量可以无限期增加,更新必须在所有架构之间复制,数据库的连接池必须为每个租户维护不同的连接(或一组凭据),每个租户(存储在服务器级别)需要一个不同的用户,并且您必须独立备份该用户。

第四选择

行隔离。

在此选项,服务器,数据库和架构中,所有内容都是共享的。租户的所有数据都在同一数据库的同一表中。区分它们的唯一方法是基于TenantId表级别上存在的一个或某些其他列。

另一个好处是,您将不需要复杂的devops策略,并且如果您使用的是SQL Server,我知道,存在一个称为行级安全性的资源,您只能获取登录用户具有权限的数据。

但是在这种情况下,如果您有成千上万的用户将同时访问数据库,则将需要一些方法来实现良好的可伸缩性。

因此,您需要考虑您的情况以及系统如何成长,以选择更好的选择。

  • @James 是的,如果没有更多背景,我们无法帮助我们的朋友,但我可以尝试让一些选项来澄清您的想法 (3认同)

小智 0

对我来说似乎很好。

我认为瓶颈在于每个租户都位于单独的数据库服务器或数据库实例上。这意味着您需要为每个租户保留一个单独的连接池,或者根据租户为每个请求创建一个新连接。尝试使用任何可以为所有租户建立一个数据库连接的概念(命名空间、模式或只是在租户表名称前添加一些特定于租户的前缀)

但是,如果您需要将租户数据库分开,例如。由于不同的备份策略、资源限制等,您无法执行此操作,并且必须为每个租户管理单独的连接池。这还取决于您有多少租户。几十、几千?

我还建议您将租户->数据库映射缓存在应用程序中的某个位置,而不是每次都从核心数据库查询它。