假设我有一个数据存储类型,下面列出了两个属性,并且整体插入率极高(但random_key
个别值的插入率很低):
random_key
- 统一分布的大号time
- 一个单调递增的时间戳,表示实体的插入时间我主要关注复合索引(random_key ASC, time DESC)
的查询,而我并不关心time
字段的查询。
问题:但是根据数据存储区文档,创建此复合索引要求我不要从自动索引中排除random_key
和time
字段。根据最佳实践,time
上的索引将导致热点问题,因为它会单调增加。
Google datastore - index a date created field without having a hotspot等其他问题建议在时间戳前加一个随机值来对数据进行分片。但是我想尝试一种干净的方法,在另一个单独的属性中使用更有意义的值random_key
问题:
我可以选择在两个字段上维护复合索引,而不会仅在time
上出现与自动索引相关的任何问题?
答案 0 :(得分:1)
单独time
排除/忽略自动索引上的热点问题并不能真正改变/改进复合索引的内容:您仍然遇到更新索引的问题(一个复合的,但这并没有真正有所作为)具有单调增加的属性值,这仍然受到热点问题的影响。
这是因为App Engine datastore tip: monotonically increasing values are bad中图解说明的热点问题的根本根本原因是索引更新工作负载可以分配到的工作线程数:
单值更改属性值连续索引更新请求往往会持续命中同一个工作线程,只能以序列化方式执行它们 - 热点
具有随机/均匀分布的属性值连续索引更新请求可以统计分布给多个工作并行执行。这正是分片正在为单调改变属性所做的事情。
您引用的问题的答案同样适用于复合索引案例:如果更新率高于上述500写入/秒的临界点,则可以对time
使用分片。
但分片会使您的应用变得复杂:您需要多次查询和客户端合并结果。如果您的random_key
确实更有意义,那么可能会发现它更具吸引力,而不是:
time
无索引(从而避免全部热点)random_key
进行查询(不需要复合索引),只需通过客户端处理(可能处理)来处理time
过滤而不是组合分片查询的结果。)