查看原文
其他

如何使用 Postgres 对一个多租户应用分片 (Sharding)

天舟 Bytebase 2024-07-09


原文 Sharding a multi-tenant app with Postgres https://www.citusdata.com/blog/2016/08/10/sharding-for-a-multi-tenant-app-with-postgres/。
无论您是在构建营销分析、电子商务门户还是给不同学校的应用程序,或者您正在构建的是一个面向其他企业客户的应用程序,那么多租户 (multi-tenant) 就是常态。相同的代码适用于所有客户,但每个客户只能看到自己的私有数据集,除了有时需要看一些整体内部报告。

在应用程序生命周期早期,客户数据具有简单结构,并会自然演变。通常所有信息都与中心的客户/用户/租户表相关联。当数据量较小(几十 GB)时,通过增加更多硬件来扩展应用程序很容易实现;但当您业务取得足够成功并且数据不再适合单台服务器内存或需要更高并发性时会怎样呢?你需要进行横向扩展 (scale-out),通常这会很痛苦。

这种横向扩展模型对谷歌和 Instagram 等公司效果良好,但也不必像你想象的那样复杂。如果能以正确方式对多租户数据进行建模,则分片 (sharding) 可以变得更简单,并仍然为您提供数据库所需功能包括连接、索引等强大功能。虽然 Citus 让您可以扩展处理能力和内存空间,请注意如何对数据进行建模可能影响系统带给您便利性和灵活性程度。如果要构建一个多租户 SaaS 应用程序,希望以下示例能显示如何在早期规划扩展而无需过度改动应用程序结构。

租户

在大多数面向非消费者应用程序的核心,租户已经内置了,无论您是否意识到。正如我们上面提到的,您可能有一个用户表。让我们看一个突出这一点的非常基本的 SaaS schema:
上面的架构突出了一个过于简化的多租户电子商务网站。比如说像 Etsy 这样的网站。当然,你可能会对此运行一些查询:
列出特定店铺的产品:
或者说,您想计算特定商店每周存在多少购买次数:
从这里,您可以设想如何为每个商店提供独特的存在和分析。现在,如果我们快进一点并开始考虑扩展这个项目,那么我们需要在数据划分方面做出选择。最容易实现此目标的级别是租户级别或者在本例中是商店 ID。根据上述数据模型,随着时间推移,最大的表很可能是产品和购买记录,我们可以按照这两者进行数据划分。不过如果我们选择产品或购买记录,则困难之处在于可能希望执行关注某些项目(例如商店)的查询。如果我们选择商店 ID,则特定商店的所有数据将存在于同一个节点上,这将使您能够直接将所有计算下推到单个节点上。

多租户和共置(co-location),天生一对

将数据放置在同一物理实例内,避免在连接期间通过网络发送数据。这可以导致操作速度更快。使用 Citus 有许多方法来移动您的数据,以便以灵活的方式进行连接和查询,但对于这类多租户 SaaS 应用程序而言,如果您能确保数据最终位于 shard 上,则很简单。不过要做到这一点,我们需要将 store id 推送到所有表中。
使所有这些成为可能的关键是在所有表上包含 store_id。通过这样做,您可以轻松地将所有数据分片出来,使其位于同一个 shard 上。在上述数据模型中,在我们的所有表上正好都有 store_id,但如果没有该字段,则可以添加它。这会让您处于有利位置,以便分发存储在相同节点上的全部数据。现在让我们尝试对租户进行分片,在本例中是商店:
现在一切都准备就绪。再次注意,我们按 store_id 对所有内容进行了分片——这样可以将所有查询路由到单个Postgres 实例。只要您的查询中包含 store_id,之前的相同查询应该能够正常工作。您当前数据的布局可能如下所示:
合置之外的另一个方案是选择一些更底层的分片键,例如订单或产品。这样做会产生一个权衡,Join 和查询变得更加困难,因为您必须通过网络发送更多数据,并确保事情以分布式方式运行。如果您的分析总是针对整个数据集进行(通常在度量重点用例中经常发生),那么这种更底层的分片键会对面向消费者场景的数据集更有帮助。

结论

在我们之前的帖子中提到,不同的分发模型可能具有不同的优势和权衡。在某些情况下,建模于较底层的实体 ID(如产品或购买信息)可能是正确的选择 - 您可以获得更多用于分析的并发,并牺牲查询单个商店的简单性。选择采用多租户数据模型或采用更分布式的文档模型都可以进行扩展,但每种选择都各有利弊。如果您今天需要扩展您的多租户应用程序,请尝试使用 Citus;如果对哪种方法最适合您当前情况有任何疑问,请随时与我们联系。我们可以提供帮助。


这篇文章的作者 Craig Kerstiens 也是 Postgres 老兵了,曾先后在 Heroku, Citus Data (后被微软收购)。目前在 Crunchy Data 担任 Chief Product Officer。这篇文章写于 2016 年,当时作者仍然在 Citus Data 任职。虽然是 8 年前的文章,但其中的建议并没有过时。如今还出现了把构建多租户应用作为卖点的 Postgres服务 https://www.thenile.dev/
如果您给不同的租户创建了完全独立的数据库,那么如何统一地变更这些数据库就是一个很头疼的问题。Bytebase 提供了这样针对多租户的方案,叫做批量模式 (batch mode)。用户可以创建数据库组和数据库表组,把同构的数据库组织起来,进行统一的批量变更和批量查询。

Bytebase 签约极氪,规范数据库访问,提升跨国团队协作效率,确保数据合规

搭建基于 Snowflake 的 CI/CD 最佳实践!

四年增长 100 倍的 Figma,数据库团队是怎么活下来的!

80岁图灵奖得主再度出山,打造基于数据库的云原生操作系统 DBOS


继续滑动看下一个
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存