【问题标题】:Google App Engine Datastore sharding in GoGo 中的 Google App Engine 数据存储分片
【发布时间】:2015-12-14 11:25:23
【问题描述】:

我在 GAE 中创建了一个分片,但只是有时,在运行分片代码后并不总是收到此消息。

(datastore_v3: BAD_REQUEST): Key path element must not be incomplete: [ResumeShard: ]

代码:

//Sharding
//Getting shard ID
rand.Seed(time.Now().UnixNano())
shardId := rand.Int63n(5)
resumeShardKey := datastore.NewKey(*pC, "ResumeShard", "", accountKey.IntID()+shardId, nil)

var resumeShard param.ResumeShard

if 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(..)

请提出建议。

【问题讨论】:

    标签: google-app-engine go google-cloud-datastore sharding


    【解决方案1】:

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

    并引用datastore.Key的文档:

    stringIDintID 之一或两者必须为零。如果两者都为零,则返回的密钥不完整。

    intID 获得0 的机会是五分之一,即 20%(这接近您报告的 10 分之三)。

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

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

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

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

    【讨论】:

    • 你真是个专家!非常感谢您的帮助!
    猜你喜欢
    • 2010-11-03
    • 2012-09-07
    • 2012-05-11
    • 2011-05-26
    • 2011-12-09
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多