【问题标题】:Monotonically increasing fields in composite indexes复合索引中的单调递增字段
【发布时间】:2018-04-17 01:45:59
【问题描述】:

假设我有一个 Datastore 类型,它具有下面列出的两个属性,并且总体插入率非常高(但 random_key 的单个值的插入率很低):

  1. random_key - 一个均匀分布的大数
  2. time - 表示实体插入时间的单调递增时间戳

我主要关心对复合索引 (random_key ASC, time DESC) 的查询,而不关心仅对 time 字段的查询。

问题:但根据数据存储文档,创建此复合索引要求我不要从自动索引中排除 random_keytime 字段。根据最佳实践,在time 上建立索引会导致热点问题,因为它是单调递增的。

Google datastore - index a date created field without having a hotspot 等其他问题建议在时间戳前添加一个随机值以对数据进行分片。但我想尝试一种干净的方法,在另一个单独的属性random_key

中使用更有意义的值

问题: 我有哪些选择可以维护两个字段的复合索引,而不会出现与 time 上的自动索引相关的任何问题?

【问题讨论】:

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


    【解决方案1】:

    仅在 time 上排除/忽略自动索引的热点问题并不能真正改变/改进复合索引:您仍然遇到更新索引的问题(复合索引,但是这并没有真正的区别)具有单调增加的财产价值,这仍然是热点问题。

    这是因为热点问题的根本原因(在 App Engine datastore tip: monotonically increasing values are bad 中以图形方式说明)是索引更新工作负载可以分配到的工作线程数:

    • 随着属性值的单调变化,连续的索引更新请求往往会不断命中同一个工作线程,该工作线程只能以序列化方式执行它们 - 热点

    • 具有随机/均匀分布的属性值的连续索引更新请求可以统计分布到多个工作人员以并行执行。这也是分片对单调变化的属性所做的事情。

    您提到的问题的答案同样适用于复合索引情况:如果更新速率高于提到的 500 次写入/秒的临界点,您可以对 time 使用分片。

    但是分片会使您的应用复杂化:您需要多个查询和客户端合并结果。如果您的random_key 确实更有意义,您可能会发现它更有吸引力,而不是:

    • 保持 time 未编入索引(从而避免一起出现热点)
    • 仅通过random_key 查询(不需要复合索引)并通过客户端处理简单地处理time 过滤(这可能比合并来自分片查询的结果的处理更少)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-25
      • 2012-11-16
      • 2018-06-02
      • 1970-01-01
      • 2019-08-14
      • 2014-06-12
      • 1970-01-01
      相关资源
      最近更新 更多