为了账号安全,请及时绑定邮箱和手机立即绑定

Go 中的 Google App Engine 数据存储分片

Go 中的 Google App Engine 数据存储分片

Go
拉莫斯之舞 2021-11-29 16:11:14
我在 GAE 中创建了一个分片,但有时在运行分片代码后并不总是收到此消息。(datastore_v3: BAD_REQUEST): Key path element must not be incomplete: [ResumeShard: ]编码://Sharding//Getting shard IDrand.Seed(time.Now().UnixNano())shardId := rand.Int63n(5)resumeShardKey := datastore.NewKey(*pC, "ResumeShard", "", accountKey.IntID()+shardId, nil)var resumeShard param.ResumeShardif err = datastore.Get(*pC, resumeShardKey, &resumeShard); err != nil {    if err == datastore.ErrNoSuchEntity {        resumeShard = param.ResumeShard{}        resumeShard.Counter = 1    } else {        log.Println(err.Error())    }} else {    resumeShard.Counter += 1}*pC 是指向来自 appengine 的上下文的指针。accountKey是Key每个用户唯一的数据存储。此错误随机出现,例如 10 个请求中出现 3 次。我想知道因为我必须使用datastore.NewKey(..)为分片创建密钥,我怎样才能获得调用后我将收到的完整密钥,Put(..)因为这是分片并且 GAE 文档上的示例也使用datastore.NewKey(..)。请建议。
查看完整描述

1 回答

?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

您收到一条错误消息,指出您提供的密钥不完整。这是因为您指定了一个空的键名 ( "") ( stringID),并accountKey.IntID()加上一个随机数(来自范围0..4- 两者都包括在内)作为数字键 ID ( intID)。请注意,如果您accountKey.IntID()的未初始化,它将是0并且随机数也可能是0在这种情况下 a0用作intID.

并引用以下文档datastore.Key

stringID和 中的一个或两个都intID必须为零。如果两者都为零,则返回的密钥不完整。

得到的机会0intID1,总分5为20%(这是靠近您报道3满分10分)。

的值0intID是无效的,它必须是一个非零值作为0是一个特殊值就像空字符串""stringID,这两者都用于表示其他属性用于标识该实体; 或者 - 如果两者都是零值 - 表示密钥是不完整的密钥(因此需要系统随机分配intID)。

请注意,此解决方案很糟糕,因为您使用具有相对数字 ID ( intID) 的键,与帐户键 ( accountKey.IntID())的数字 ID 相比是相对的。系统分配的密钥将随机分配,但有可能 2 个帐户密钥可能彼此接近(例如,一个是另一个 +1)。在这种情况下,您的分片键会重叠!

如果datastore.Put()用来保存实体,系统分配的随机key就是返回值Put()

func Put(c context.Context, key *Key, src interface{}) (*Key, error)


查看完整回答
反对 回复 2021-11-29
  • 1 回答
  • 0 关注
  • 152 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信