2015-12-14 47 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

相關問題