多租户还是多实例?

18
我正在尝试构建一个基于Web的SaaS解决方案,但我遇到了一个问题,我不确定是否要使用多租户或多实例。我将尝试描述我想要实现的内容以及每种方法的优缺点(根据我所读的)。请在一种方法比另一种方法更好时提出您的建议。
我正在构建的应用程序是一个SaaS解决方案,公司可以创建自己的帐户,每个帐户/公司都有自己的用户、客户、产品、服务等。每个与帐户/公司相关联的用户(公司员工)仅能访问其公司的客户、产品和服务。公司可以拥有无限数量的客户、产品和服务,因此每个公司都应该有自己的数据中心。
为此,我决定创建一个共享数据库(保存所有用户凭据以进行登录)和多个数据库共享模式(每个帐户/公司一个数据库)。基本上,这就是多租户。
有人建议使用多租户,其中每个公司将拥有自己的应用程序实例(即代码、库、数据库、框架等),完全与其他公司分开。这听起来更好,因为我不必再关注额外的层次,在那里我需要确保每个租户的用户只能访问其公司的数据。值得一提的是,我依赖Docker来实现这种方法(我以前从未使用过它),但我认为它缺少我将来需要的功能(稍后会更详细地介绍),至少我在搜索中没有找到它们。

然而,每种方法都有其优缺点,所以我无法决定选择哪种方法。以下是一个列表,但请容忍我对它们的知识不足,因此可能存在我不知道的问题或者我没有在网上找到的问题的解决方案:[每种方法都有一个有序列表,我按照顺序逐一进行比较]

多租户

  1. 共享主机/硬件,共享代码和多数据库。
  2. 扩展代码功能并修复错误更容易(共享代码)。
  3. 要扩展硬件(可以使用云服务)或将个别租户的数据库移动到另一个系统而不对代码进行更改,则更难。
  4. 最重要的是,正如我之前提到的,我需要向系统添加额外的层,以确保用户实际上属于他/她的公司,而不是访问其他公司的信息。

多实例:

  1. 共享或不共享主机/硬件,每个实例有自己的代码和数据库。
  2. 要扩展功能或修复错误更加困难(我不确定是否有一种方法在Docker中可以向一个实例或Docker容器添加功能/特性,并将其部署到其他实例中)。
  3. 将整个实例移动到不同的主机/硬件更容易。
  4. 作为实例,我不需要考虑那一层,因为每个实例都有自己的数据库。
如果我想手动执行任何操作(例如手动为每个租户创建一个实例),则所有优缺点都是多余的,这就是我对Docker解决方案持怀疑态度的原因,除非有一种解决方法,这也许是问题的主要原因。如果您能提供解决方案并说明为什么这种方法比其他方法更好,我将不胜感激。
如果有帮助的话(也许?),我们使用Laravel作为后端的主要框架(全部都是RESTful)。

3个回答

8
如果客户们将使用共享模式,那么您不需要为每个客户都拥有不同的数据库。大多数SaaS软件都是多租户的,并以这种方式工作,即使用一个公共数据库和应用程序逻辑来确保用户只能访问他们被允许访问的内容。例如,Facebook没有数十亿个数据库,每个用户一个,来确保我们无法看到彼此的非公开照片。
另外,您试图解决的问题似乎不应该对您的应用程序的可移植性或您将其移到云端的能力产生任何影响。如果您将后备服务(例如数据库)视为附加资源,那么您是否拥有一个或多个并不重要(尽管我仍建议您只拥有一个)。
我建议阅读SaaS开发和部署的12因素原则。它们是思考如何构建可以轻松在云本地环境中工作的软件的绝佳起点。我会专注于解决您的软件业务问题,并按照12因素原则构建云本地化的架构。

根据您所描述的问题,似乎Docker与非Docker并不是当前需要关注的问题。也就是说,您提出的所有方法都可以在有或没有Docker的情况下进行类似的操作。Docker解决了进程隔离、打包操作系统级依赖项、减少计算资源开销、开发和生产环境之间的一致性等问题,似乎只与您所追求的内容间接相关。


谢谢你的回答。我明白你为什么说我不需要每个租户一个数据库,因为我有一个共享模式,但我的假设基于两点:首先,一个租户可能在他/她的数据中心拥有大量数据,而另一个租户则较少。所以那个数据较少的租户可能会遇到性能问题(也许?)。其次,一些租户可能需要扩展服务(需要新表),将其包含在一个租户的数据库中(添加代码)比在一个数据库中修改代码更容易... - Asher
3
首先,一个租户可能在他/她的数据中心拥有大量数据,而另一个租户则可能较少。因此,那个数据量较少的租户可能会遭受性能方面的问题(也许?)或者也可能不会。有比为每个租户使用不同的数据库更好的解决查询优化的方法。其次,一些租户可能需要扩展服务(需要新的表),将其包含在一个租户的数据库中(添加代码)比在一个数据库中进行修改代码更容易。这种情况下,有更好的、更符合云原生模式的解决方案。 - Amit Kumar Gupta
5
您可以考虑采用类微服务的架构。您可以拥有一个单一的前端,通过API与不同的后端服务通信,并仅向给定用户公开相关服务。为不同的服务使用不同的数据库是有意义的,而不是为不同的租户使用不同的数据库。我不会从每个用户都会得到完全不同的服务的计划开始。 - Amit Kumar Gupta
给你的回答和评论点个赞 :) - Asher

6
多租户是未来的发展方向,它既节省成本又易于维护。想象一下,如果您的应用程序有10个客户,每个客户使用不同版本的应用程序,那么支持他们将成为一个大问题。有了多租户,您可以根据负载自动扩展并在负载减少时缩小规模;而对于多实例,则必须确保为每个客户提供至少一个实例。
以下是我选择多租户的其他原因:
  1. 只需构建和部署一个版本
  2. 共享诸如缓存之类的资源
  3. 仅测试应用程序的一个版本
  4. 简化安全性测试
  5. 有效利用CDN

4
其他人之前也遇到了这些问题。例如,有一个叫做SaaS成熟度模型的东西。我认为大多数成功的模型都是先从功能开始考虑,然后再考虑平台。所以我会首先采用每个客户实例的策略。无论如何,一开始会有多少客户?失败更可能是因为客户不喜欢功能还是因为你使用了多个实例,当然带来了运营开销?
=> 首先关注产品/功能。因此,首先目标是达到第一级,然后再关注其他级别。
对于Docker(至少从我作为一个人的角度来看,没有太多与之相关的经验):您的开发工件是可运行的容器映像。当将此工件发布到存储库时,应该很容易更新所有实例以使用此新工件。因此,通过一些脚本和类似于Kubernetes的东西,甚至可以将许多实例移动到新版本。因此,我认为像Docker这样的新开发使得多实例设置变得更加可行。
我正在为公司开发一款SaaS产品。由于业务考虑,我们也需要支持多实例:
  1. 我们的客户非常注重将数据与竞争对手分开。这可以通过采用多实例策略更容易地实现。
  2. 有时客户想要控制发布周期。例如,他们必须向员工传达功能变化,或者正在进行某个业务流程,无法进行升级。因此,他们可能希望等待新版本甚至跳过它。使用每个客户一个实例会更容易实现这一点。
像这样的问题,我的回答只是基于我的观点和经验。 SaaS有很多种形式,实际情况还需具体分析。

谢谢。我将首先回答您的问题。一开始会有两个客户(公司),因此会有两个实例。对于第二个问题,只是另一个SaaS,它可能成功也可能失败,但至少会有两个客户。整个事情取决于用例是可以理解的,但您引用的成熟度模型将多实例解决方案视为较低级别(级别1),而将其他多租户解决方案(级别2)视为较高级别,但我并不这样认为。它也没有提到从一个级别转移到另一个级别的任何内容... - Asher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接