1 Introduction
Speaking Golang of Redis library, probably the most used
redigo and Go-Redis . Which redigo
does not support access to the cluster.
This article would like to talk about go-redis
two Advanced Usage
2. Enable access to the Slave Node of Cluster
In a relatively high load of Redis Cluster, if allowed to read will greatly improve the handling capacity of the slave node cluster.
Open access to the Slave nodes affected by the following three parameters
type ClusterOptions struct {
// Enables read-only commands on slave nodes.
ReadOnly bool
// Allows routing read-only commands to the closest master or slave node.
// It automatically enables ReadOnly.
RouteByLatency bool
// Allows routing read-only commands to the random master or slave node.
// It automatically enables ReadOnly.
RouteRandomly bool
...
}
go-redis
Logical nodes selected as follows
func (c *ClusterClient) cmdSlotAndNode(cmd Cmder) (int, *clusterNode, error) {
state, err := c.state.Get()
if err != nil {
return 0, nil, err
}
cmdInfo := c.cmdInfo(cmd.Name())
slot := cmdSlot(cmd, cmdFirstKeyPos(cmd, cmdInfo))
if c.opt.ReadOnly && cmdInfo != nil && cmdInfo.ReadOnly {
if c.opt.RouteByLatency {
node, err := state.slotClosestNode(slot)
return slot, node, err
}
if c.opt.RouteRandomly {
node := state.slotRandomNode(slot)
return slot, node, nil
}
node, err := state.slotSlaveNode(slot)
return slot, node, err
}
node, err := state.slotMasterNode(slot)
return slot, node, err
}
- If ReadOnly = true, select only
Slave Node
- If ReadOnly = true and RouteByLatency = true from the
slot
correspondingMaster Node
andSlave Node
selection, selection policy is: SelectPING
delay the lowest node - If ReadOnly = true and RouteRandomly = true from the
slot
correspondingMaster Node
andSlave Node
selection, selection policy: random selection
3. Use the pipeline function in a clustered mode
Redis principle function of the pipeline is a one-time Client will be sent to multiple redis command Redis Server, reducing the IO overhead of each command are transmitted. While reducing the number of system calls, and thus enhance the overall handling capacity.
We in the main - from Redis mode, pipeline function should be used a lot, but in Cluster mode, it is estimated that few people used.
We know redis cluster default allocated 16,384 slot, when we set a key, will use CRC16 algorithm to get modulo belongs slot
, then the node will be assigned to this key hash slot interval, the specific algorithm is: CRC16 (key )% 16384. If we use the pipeline function, multiple commands in a batch contained, key each command involved may belong to differentslot
go-redis
To solve this problem, three steps
source can read defaultProcessPipeline
. 1) will be calculated command
belongs slot
, according to slot
choose the right Cluster Node
) with a 2 to Cluster Node
all command
, in a batch transmission (concurrent operation)
3) reception result
Note: This go-redis
order is simple, each command
can only involve a key
, or you may receive the following error
err CROSSSLOT Keys in request don't hash to the same slot
That go-redis does not support a similar MGET
command usage
A simple example
package main
import (
"github.com/go-redis/redis"
"fmt"
)
func main() {
client := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{"192.168.120.110:6380", "192.168.120.111:6380"},
ReadOnly: true,
RouteRandomly: true,
})
pipe := client.Pipeline()
pipe.HGetAll("1371648200")
pipe.HGetAll("1371648300")
pipe.HGetAll("1371648400")
cmders, err := pipe.Exec()
if err != nil {
fmt.Println("err", err)
}
for _, cmder := range cmders {
cmd := cmder.(*redis.StringStringMapCmd)
strMap, err := cmd.Result()
if err != nil {
fmt.Println("err", err)
}
fmt.Println("strMap", strMap)
}
}