命名空间和祖先在数据结构上的区别

Difference between namespace and ancestor in data structure

之间有什么区别
key := datastore.NameKey("user", userID, nil)
client.Put(ctx,datastore.IncompleteKey("session",key),&sessionUser)

key :=&datastore.Key{Kind:"session",Parent:nil,Namespace:userID}
client.Put(ctx,key,&sessionUser)

如果它们都具有可能导致 contention 的相同 write/read,为什么它们会不同 从此article

Cloud Datastore prepends the namespace and the kind of the root entity group to the Bigtable row key. You can hit a hotspot if you start to write to a new namespace or kind without gradually ramping up traffic.

因此,我真的很困惑应该如何支撑我的数据, 顺便说一句,阅读时哪个更快?

不同之处在于,您提到的名称空间争用极端情况只是一个暂时的情况,等效(从根本原因的角度来看),如果您愿意,可以使用 this one:

...

If you create new entities at a very high rate for a kind which previously had very few existing entities. Bigtable will start off with all entities on the same tablet server and will take some time to split the range of keys onto separate tablet servers.

...

瞬态仅持续到发生足够的平板电脑拆分以跟上写入操作速率。对于您引用的情况,逐渐增加流量将为这些拆分留出时间,然后再出现错误,从而避免出现此问题。即使没有逐渐增加 - 争用也可能只发生到分裂发生,之后它就消失了。

另一方面,使用祖先会引发一个不同类型的永久性问题。共享相同祖先的所有实体都被放置在同一个实体组中,因此每个实体组都共享每秒最大 1 次写入的速率。组越大,争用的风险就越高。使用非祖先相关实体(有或没有命名空间)有效地创建大小为一的实体组 - 这种类型的最小争用。

因此,除非您真的非常需要祖先,否则如果您的预期使用模式留有争用空间,我建议您尽量避免使用它。

旁注:该文章仅涉及写入争用,但您应该知道争用也可能发生在读取时(在事务中),请参阅 。在这种情况下,实体组大小很重要,事务试图锁定整个实体组。