【问题标题】:Increasing Google Cloud DataStore Composite index limit增加 Google Cloud DataStore 复合索引限制
【发布时间】:2018-01-22 18:34:23
【问题描述】:

我使用谷歌应用引擎作为我的后端和数据存储作为数据库。链接https://cloud.google.com/datastore/docs/concepts/limits表示一个项目的最大复合索引数不能超过200。 我的项目中有大约 130 个复合索引,将来某个时候会达到限制。

200 的限制对我来说似乎非常少。 假设我的项目中有 5 个模块,每个模块都有 10 个“种类”。在每种类型中,我都有 4 个要索引的属性(我们称它们为 prop1、prop2、prop3 和 prop4)。此外,每个“种类”都有一个名为 creationTime 的字段,它存储实体在数据存储中创建的时间。无论我应用 0、1、2、3 还是全部 4 个过滤器,我总是希望我的实体列表按creationTime 排序,最新的在前。

在我看来,这是一个完全合理的场景。在这种情况下,对于每个“种类”,我必须定义以下复合索引

<datastore-index kind="kind1" ancestor="false">
        <property name="prop1" direction="asc" />
        <property name="creationTime" direction="desc" />
</datastore-index>
<datastore-index kind="kind1" ancestor="false">
        <property name="prop2" direction="asc" />
        <property name="creationTime" direction="desc" />
</datastore-index>
<datastore-index kind="kind1" ancestor="false">
        <property name="prop3" direction="asc" />
        <property name="creationTime" direction="desc" />
</datastore-index>
<datastore-index kind="kind1" ancestor="false">
        <property name="prop4" direction="asc" />
        <property name="creationTime" direction="desc" />
</datastore-index>

既然有 50 个这样的种类,那么就有 200 个这样的索引。现在我知道,如果我不按创建时间对实体列表进行排序,我可以避免这些索引,但我认为从用户的角度来看这将是非常糟糕的。

那么有没有办法增加/克服限制? 我在这里错过了什么吗? 我需要限制我的查询吗?如果是,那么我怎样才能获得相同的用户体验? 数据存储不是用于此类查询吗?我有什么选择?

【问题讨论】:

    标签: google-app-engine google-cloud-platform google-cloud-datastore


    【解决方案1】:

    您无法增加限制,因此您应该查看您的数据模型。

    首先,让我们澄清一下术语:您所说的“实体”实际上称为“种类”。实体是一种类型中的单个记录。

    查看您的种类,看看它们在语义上是否真的不同,或者它们是否真的非常相似(许多重叠的属性)。如果它们相似,您可以将它们全部归为同一种类并添加一个属性来区分它们;我们称之为type 属性。

    例如,除了trolls、zombies 和 witches 的不同种类,您可以有一个称为 monsters 的单一种类。

    现在,您的示例索引:

    <datastore-index kind="Entity1" ancestor="false">
            <property name="prop1" direction="asc" />
            <property name="creationTime" direction="desc" />
    </datastore-index>
    

    如下:

    <datastore-index kind="Master" ancestor="false">
            <property name="type" direction="Entity1" />
            <property name="prop1" direction="asc" />
            <property name="creationTime" direction="desc" />
    </datastore-index>
    

    这样做的好处是过滤prop1 并按creationTime 排序只需要一个复合索引,而不管类型的数量。因此,在您的 50 种示例中,而不是 50 个复合索引来涵盖每种类型,您现在只有 1 个。

    【讨论】:

    • 是的,我的意思是 Kind 而不是实体,感谢您指出。我在我的问题中更正了它。但是我的种类是不同的,或者至少大多数是不同的,我认为将它们组合成一个单一的种类在语义上是没有意义的。还有其他选择吗?
    【解决方案2】:

    我认为克服这种限制的唯一选择是将您的模块分散到多个应用程序中,如果需要,甚至每个应用程序一个模块,基本上遵循Project isolation GAE 微服务架构方法:

    如果您不想依赖这些模式来实现隔离和 你想要一个更正式的分离执行,你可以使用多个 App 引擎项目。改用项目有利有弊 服务,并且您必须根据您的 情况。除非您特别需要其中一项优势 通过使用多个项目提供,最好从使用开始 单个项目中的多个服务,因为性能将 更好,管理开销将最小化。当然, 你也可以选择两种方法的混合。

    最大索引限制是多个项目的优势之一,总体而言,您可以将限制乘以项目数量。

    在该部分的正下方,有一个与您当前使用的 Service isolation 架构的比较。

    但这种方法只有在您的每个模块使用的索引少于限制时才有用。如果其中任何一个需要更多,您将不得不重新设计它。

    更新:

    另一种可能的方法是优化您的索引使用,在某些情况下可以通过以下方式处理多个不同的查询:

    但是,在某些情况下无法知道确切的 提前查询的形式,例如查询的过滤器是 根据用户输入动态构建。在这些情况下,所有 索引必须支持过滤器的可能组合 由应用程序定义。传统上,这需要一个 combinatorial explosion 定义的索引数。最近的 enhancements to the App Engine Datastore查询规划器有 消除了对这种扩散的要求 应用程序的索引。本文介绍了如何充分利用 这些增强功能的优势。

    ...

    索引总数为 2^(过滤器数量) * (过滤器数量 不同的顺序)= 2 ^ 5 * 4 = 128 个索引

    可以指定这么多索引,但这样做有风险:

    • 可能超过指数上限 (200)
    • 每个实体的storage cost 大大增加(因为此成本包括索引条目的大小)

    ...

    所需的索引条目数为(过滤器数 + 1)* (订单数)= 7 * 4 = 28。这是一个更易于管理 数字。此外,这些指数都没有爆炸式增长,因此 额外的storage cost 实体也同样小。

    【讨论】:

      猜你喜欢
      • 2020-09-06
      • 2021-01-13
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 2014-03-30
      • 1970-01-01
      • 2015-03-22
      • 2020-01-30
      相关资源
      最近更新 更多