【问题标题】:Criteria and strategy for partitioning a large table in PostgresPostgres中大表分区的标准和策略
【发布时间】:2020-06-18 14:18:49
【问题描述】:

我们正在考虑将我们的应用迁移到多租户数据库。目前,该应用程序使用每个租户一个数据库运行。目前约有400名租户。合并后,最大的表将有大约 10 亿行,并且会随着租户的增加而增长。租户的大小差异很大,仅一个租户在该表中就有 1.8 亿条记录,有些不到 100 万条。数以亿计的还有其他几张桌子,大多数桌子的数量要少得多。我主要关注的是大型表的可伸缩性规划,我将专注于最大的表。它的参数是它是一个链接/多对多表,其中包含创建者和创建日期的基本审计字段(尽管我质疑这些字段是否甚至是必要的)。日期/时间与此无关,这是一个分配表,始终适用。记录可以被删除或插入,而不是更新,有时是批量的,可能不经常发生,但随时可能发生。我认为两个外键的数据基数都相对较高,尽管我不确定高基数与记录总数的比率是什么。从某种角度来看,拥有 1.8 亿条记录的租户对于一个外键有大约 100,000 条不同的记录,而对于另一个外键则有 165,000 条。同时,另一个客户有大约 180,000 条记录,一个字段中有 500 个不同的值,另一个字段有 5000 个。正如我所说,有很多可变性。

我上面描述的那种表(数十亿行、高数据基数、不基于时间、租户分段、随时批量插入/删除)是否会在我描述的那种场景中(400 多个租户与不同数量的数据)是否适合分区?我现在担心这一点的原因是,我在许多地方读到,如果您提前计划好分区而不是在表之后尝试分区,那么处理分区的痛苦会小得多在不需要停机时间或跳过箍的情况下,它是巨大且难以使用的。在这一点上,我主要关心的不是查询数据,我用一个有 10 亿条记录的表进行了测试,并且使用适当的索引选择查询运行得非常快。我更担心读/写/删除的并发性,由于锁而陷入阻塞等。如果分区是必要的,那么好的策略是什么?按租户划分?把大的分开,把小的捆绑在一起?

【问题讨论】:

    标签: postgresql scalability


    【解决方案1】:

    鉴于您说查询性能不是问题,我能想到考虑分区的唯一原因是使大规模清除更容易完成。

    您是否制定了合同或法律保留政策?

    最常见的情况是使用时间段作为您的分区键,以便滚动旧数据只是删除分区的问题,但由于您明确指出日期/时间不相关,我不明白这是怎么回事会有帮助的。

    您是否经常滚动/滚动单个客户?是否有清除或保留要求?如果是这样,那么无论分区有多么不平衡,按客户进行分区都是有意义的,因为您可以清除大客户的数据而不影响其他客户对其数据的访问。

    对于任何并发问题,按客户进行分区应该有助于将这些问题包含在表现出大量活动的特定客户中。

    出于以下几个原因,我建议彻底测试一下:

    • 我没有看到多个活动分区在起作用,因为我只使用时间序列分区
    • 我没有深入研究过PostgreSQL 12's foreign key enhancements,想知道两边都有分区表的外键是否会使删除分区复杂化
    • 我从未探索过数据库可以包含的分区数量的实际限制

    我可能从我的经验中了解到您关于分区的问题,但您是否考虑过每个客户的架构?

    【讨论】:

    • 我们确实考虑过采用模式路线,但它确实存在一些与每个客户的数据库相同的问题。如果部署出现问题,您必须管理所有这些模式并处理迁移/回滚所有这些模式。多租户将使我们能够最大限度地提高资源使用效率。使用 RLS 可以很好地实现隔离,因此这取决于随着某些表的增长,性能可以保持多好。我认为时间范围对某些人有用,但遗憾的是,最大的时间范围不是特定日期的。
    • @Rocket04 根据我所做的工作,我主要从“这如何帮助我清除数据?”的角度考虑分区。如果这对您来说不是问题,并且您没有自然键来帮助提高性能,那么我看不出有任何分区的理由。除了分区之外,在为多租户重新设计时,我建议为客户数据所在的数据库添加一个级别,以便您在必要时灵活地移动它们。
    猜你喜欢
    • 1970-01-01
    • 2013-07-14
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    相关资源
    最近更新 更多