2015-12-14 51 views
2

我在GAE中做了一个分片,只是有时在运行分片代码后并不总是收到这条消息。Google App Engine数据存储在Go中分片

(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是指向从应用服务引擎的上下文。

accountKey是每个用户唯一的数据存储Key

此错误随机出现,如10次请求中的3次。我想知道,因为我必须使用datastore.NewKey(..)来创建分片密钥,所以在调用Put(..)后,如何获得完整的密钥,因为这是分片并且GAE文档中的示例也使用datastore.NewKey(..)

请建议。

回答

3

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

而且从datastore.Key的文档引用:

任一方或双方的stringIDintID必须为零。如果两者均为零,则返回的密钥不完整。

越来越0intID的几率是1满分为5分的20%(这是靠近您报道3满分10分)。

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

请注意,这个解决方案是坏,你用钥匙与相对数字ID(intID),相对较帐户密钥(accountKey.IntID())的数字ID。系统分配的密钥将随机分布,但有可能两个帐户密钥可能彼此靠近(例如一个是另一个+1)。在这种情况下,你的分片键会重叠!

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

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

你是一个真正的高手!非常感谢你的帮助! – Ook

相关问题