【问题标题】:Postgres Multi-tenant administration/maintenancePostgres 多租户管理/维护
【发布时间】:2014-01-18 09:29:15
【问题描述】:

我们有一个 SaaS 应用程序,其中每个租户在 Postgres 中都有自己的数据库。我如何将补丁应用于所有数据库?例如,如果我想添加一个表或向表中添加一个列,我必须编写一个循环所有数据库并针对它们执行 SQL 的程序,或者使用 pgadmin,一个一个地遍历它们。

有更聪明和/或更快的方法吗?

非常感谢任何帮助。

【问题讨论】:

    标签: postgresql database-administration multi-tenant


    【解决方案1】:

    是的,有一个更聪明的方法。

    不要为每个租户创建一个新数据库。如果一切都在一个数据库中,那么您只需要更改一个数据库。

    选择一个数据库,将每个表更改为具有 TENANT 列并将其添加到主键。然后将所有租户的每条记录插入到该数据库中,并删除其他数据库(显然比这要多得多,因为您的应用程序需要更改)。

    与您的方法的不同之处已在别处广泛讨论:

    如果您不将所有内容都放在一个数据库中,那么恐怕您必须单独更改它们,并且以编程方式进行操作会最简单。

    【讨论】:

    • 感谢您的回答。请记住,对于已经投入生产的系统,我不能只是彻底检查设计。此外,为每个租户拥有单独的数据库是为了保护每个客户的数据。是否有工具或库可以满足我的需求?
    • 在这种情况下,您已经通过编写一些代码循环访问数据库 @user2182414 来使用最简单的方法。
    【解决方案2】:

    在更高的层次上,所有多租户应用程序都遵循以下三种方法之一:

    1. 一个租户的数据保存在一个数据库中,
    2. 一个租户的数据存在于一个架构中,或者
    3. 向您的表中添加一个tenant_id / account_id 列(共享架构)。

    我发现开发人员在评估这些不同的方法时通常会使用以下标准。

    隔离:由于一方面可以将每个租户放入自己的数据库,另一方面让租户共享同一张表,这成为最明显的维度。如果您为您的用户提供原始 SQL 访问权限,或者您处于医疗保健等受监管的行业,您可能需要数据库提供严格的保证。也就是说,PostgreSQL 9.5 带有行级安全策略,这使得大多数应用程序不再担心这一点。

    可扩展性:如果您的租户共享相同的架构(方法 #3),并且您的租户具有不同的字段,那么您需要考虑如何合并这些字段。

    multi-tenant databases 上的这篇文章对不同的方法进行了很好的总结。例如,您可以添加十几个列,将它们命名为 C1、C2 等,并让您的应用程序根据租户 ID 推断该列中的实际数据。 PostgresQL 9.4 带有 JSONB 支持,并且本机允许您使用半结构化字段来表达不同租户数据之间的变化。

    扩展:另一个标准是您的数据库扩展的难易程度。如果您为每个数据库或架构创建一个租户(上面的#1 或 #2),您的应用程序可以利用现有的 Ruby Gems 或 [Django 包][1] 来简化应用程序集成。也就是说,您需要手动管理租户的数据和他们居住的机器。同样,您需要构建自己的分片逻辑来传播外键约束和 ALTER TABLE 命令。

    通过方法 3,您可以使用现有的开源扩展解决方案,例如 Citus。例如,this blog post 描述了如何使用 Postgres 轻松对多租户应用进行分片。

    【讨论】:

      【解决方案3】:

      现在是我回馈社区的时候了 :) 所以 4 年后,我们的多租户平台已投入生产,我想与大家分享以下观察/经验。

      1. 我们为每个租户使用了一个数据库。这为我们提供了极大的灵活性,因为备份中的数据库大小并不大,因此我们可以轻松地将它们导入到我们的暂存环境中以解决客户问题。

      2. 我们使用Liquibase 进行数据库开发和升级。这对我们来说是一个巨大的帮助,允许我们将整个构建打包成一个简单的 war 文件。所有更改都可以轻松进行版本控制和非常有效的管理。这里和那里有一些学习曲线,但没有什么实质性的。 2-5天可以显着节省您的时间。

      3. 鉴于我们使用 Spring/JPA/Hibernate,我们使用一种称为动态数据源路由的技术。因此,当用户登录时,我们会通过查找找到相关的数据源,并将它们连接到正确数据库的会话。这也是应用 Liquibase 脚本进行更新的时候。

      这是,目前,我稍后会回来。

      【讨论】:

        【解决方案4】:

        好吧,在我们的案例中,为所有租户使用一个数据库肯定存在问题。

        • 备份文件变大,几乎不实用,难以管理

        • 为了排除故障,我们需要在我们的开发环境中恢复客户的数据,我们只使用该客户的备份文件,而且通常该文件并不像我们为所有客户使用一个数据库一样大。

        • 同样,Liquibase 一直是允许无缝管理所有租户的更新且没有任何问题的关键。如果没有 Liquibase,我可以看到这种方法有很多复杂性。所以 Liquibase、Liquibase 和更多 Liquibase。

        • 我还怀疑我们需要更强大的硬件来管理具有数百万条记录的大型连接的大型数据库,而不是具有更小查询的更轻量级的数据库。

        • 万一出现问题,服务不会因所有人而中断,并且仅限于一个或几个租户。

        总的来说,就我们的目的而言,这是一个伟大的架构决策,我们每天都从中受益。有一次,我们有一位客户没有启用归档,他们的数据库大小增长到超过 3 GB。随着离岸团队和较慢的互联网以及存储/带宽价格,人们可以看到事情可能会很快变得复杂。

        希望这对某人有所帮助。

        --雷克斯

        【讨论】:

          猜你喜欢
          • 2023-04-10
          • 1970-01-01
          • 2014-01-16
          • 1970-01-01
          • 1970-01-01
          • 2012-07-11
          • 2017-08-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多