复合索引中的单调递增字段

Monotonically increasing fields in composite indexes

假设我有一个具有下面列出的两个属性的数据存储类型,并且总体插入率非常高(但个别值 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 上的自动索引相关的任何问题?

Excluding/ignoring time 上自动索引的热点问题对复合索引来说并不重要 change/improve:你仍然有更新问题具有单调递增 属性 值的索引(复合索引,但实际上并没有什么区别),它仍然受到热点问题的影响。

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

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

  • with random/uniformly distributed 属性 values 连续索引更新请求可以统计分布到多个worker并行执行。这也是分片对单调更改属性所做的事情。

您引用的问题的答案同样适用于复合索引情况:如果更新率高于上述临界点 500 writes/sec,您可以对 time 使用分片。

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

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