Pick random node when command does not have keys

This commit is contained in:
Vladimir Mihailenco 2017-12-28 16:41:05 +02:00
parent cfed9ab470
commit 3de5605ab2
5 changed files with 49 additions and 9 deletions

View File

@ -533,16 +533,22 @@ func (c *ClusterClient) cmdInfo(name string) *CommandInfo {
return info
}
func cmdSlot(cmd Cmder, pos int) int {
if pos == 0 {
return hashtag.RandomSlot()
}
firstKey := cmd.stringArg(pos)
return hashtag.Slot(firstKey)
}
func (c *ClusterClient) cmdSlot(cmd Cmder) int {
cmdInfo := c.cmdInfo(cmd.Name())
firstKey := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo))
return hashtag.Slot(firstKey)
return cmdSlot(cmd, cmdFirstKeyPos(cmd, cmdInfo))
}
func (c *ClusterClient) cmdSlotAndNode(state *clusterState, cmd Cmder) (int, *clusterNode, error) {
cmdInfo := c.cmdInfo(cmd.Name())
firstKey := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo))
slot := hashtag.Slot(firstKey)
slot := cmdSlot(cmd, cmdFirstKeyPos(cmd, cmdInfo))
if cmdInfo != nil && cmdInfo.ReadOnly && c.opt.ReadOnly {
if c.opt.RouteByLatency {

View File

@ -536,6 +536,32 @@ var _ = Describe("ClusterClient", func() {
Expect(nodesList).Should(HaveLen(1))
})
It("should RANDOMKEY", func() {
const nkeys = 100
for i := 0; i < nkeys; i++ {
err := client.Set(fmt.Sprintf("key%d", i), "value", 0).Err()
Expect(err).NotTo(HaveOccurred())
}
var keys []string
addKey := func(key string) {
for _, k := range keys {
if k == key {
return
}
}
keys = append(keys, key)
}
for i := 0; i < nkeys*10; i++ {
key := client.RandomKey().Val()
addKey(key)
}
Expect(len(keys)).To(BeNumerically("~", nkeys, nkeys/10))
})
assertClusterClient()
})

View File

@ -82,13 +82,13 @@ func cmdFirstKeyPos(cmd Cmder, info *CommandInfo) int {
if cmd.stringArg(2) != "0" {
return 3
} else {
return -1
return 0
}
case "publish":
return 1
}
if info == nil {
return -1
return 0
}
return int(info.FirstKeyPos)
}

View File

@ -55,13 +55,17 @@ func Key(key string) string {
return key
}
func RandomSlot() int {
return rand.Intn(SlotNumber)
}
// hashSlot returns a consistent slot number between 0 and 16383
// for any given string key.
func Slot(key string) int {
key = Key(key)
if key == "" {
return rand.Intn(SlotNumber)
return RandomSlot()
}
key = Key(key)
return int(crc16sum(key)) % SlotNumber
}

View File

@ -343,7 +343,11 @@ func (c *Ring) shardByName(name string) (*ringShard, error) {
func (c *Ring) cmdShard(cmd Cmder) (*ringShard, error) {
cmdInfo := c.cmdInfo(cmd.Name())
firstKey := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo))
pos := cmdFirstKeyPos(cmd, cmdInfo)
if pos == 0 {
return c.randomShard()
}
firstKey := cmd.stringArg(pos)
return c.shardByKey(firstKey)
}