Open liangjfblue opened 4 years ago
redis version: redis-5.0.5 redis-go-cluster version: 1.0.0
my code
cluster, err := redis.NewCluster( &redis.Options{ StartNodes: nodes, ConnTimeout: 50 * time.Millisecond, ReadTimeout: 50 * time.Millisecond, WriteTimeout: 50 * time.Millisecond, KeepAlive: 16, AliveTime: 60 * time.Second, }) if err != nil { return nil, err } fmt.Println(redis.String(cluster.Do("GET", "name")))
but when i go run, have this error
=== RUN TestNewRedisPool --- FAIL: TestNewRedisPool (0.00s) panic: runtime error: invalid memory address or nil pointer dereference [recovered] panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x544f2a] goroutine 7 [running]: testing.tRunner.func1(0xc0000ae100) /home/liangjf/app/go/src/testing/testing.go:874 +0x3a3 panic(0x5749a0, 0x6d8890) /home/liangjf/app/go/src/runtime/panic.go:679 +0x1b2 github.com/chasex/redis-go-cluster.(*redisConn).shutdown(...) /home/liangjf/ljf_home/code/go_home/pkg/mod/github.com/chasex/redis-go-cluster@v1.0.0/node.go:146 github.com/chasex/redis-go-cluster.(*redisNode).do(0xc0000b5200, 0x5ab7fa, 0x3, 0xc00004c760, 0x1, 0x1, 0x10, 0x10, 0xc00004c760, 0x546b0a) /home/liangjf/ljf_home/code/go_home/pkg/mod/github.com/chasex/redis-go-cluster@v1.0.0/node.go:192 +0x23a github.com/chasex/redis-go-cluster.(*redisCluster).Do(0xc0000ac080, 0x5ab7fa, 0x3, 0xc00004c760, 0x1, 0x1, 0x1372e4f5, 0x1372e4f50000000f, 0x5ed5b3ba, 0xc00003af60) /home/liangjf/ljf_home/code/go_home/pkg/mod/github.com/chasex/redis-go-cluster@v1.0.0/cluster.go:254 +0x20f command-line-arguments.(*RedisPool).Get(...) /home/liangjf/opensource/gpusher/common/db/redis_string.go:40 command-line-arguments.TestNewRedisPool(0xc0000ae100) /home/liangjf/opensource/gpusher/common/db/redis_test.go:23 +0x16b testing.tRunner(0xc0000ae100, 0x5b5de8) /home/liangjf/app/go/src/testing/testing.go:909 +0xc9 created by testing.(*T).Run /home/liangjf/app/go/src/testing/testing.go:960 +0x350 FAIL command-line-arguments 0.006s
at last i find the code:
func (node *redisNode) getConn() (*redisConn, error) { ... c, err := net.DialTimeout("tcp", node.address, node.connTimeout) if err != nil { return nil, err } ... }
i find that, when panic happend, the node.address is "172.16.7.16:8002@18002"
but when is normal, the node.address is "172.16.7.16:8002"
so when run in debug mode, i modified it manually "172.16.7.16:8002@18002" to "172.16.7.16:8002", it is normal
one by one to follow the code call stack, i find that
//github.com/chasex/redis-go-cluster@v1.0.0/cluster.go:609 func (cluster *redisCluster) updateClustrInfo(node *redisNode) error { info, err := String(node.do("CLUSTER", "NODES")) infos := strings.Split(strings.Trim(info, "\n"), "\n") for i := range fields { fields[i] = strings.Split(infos[i], " ") if len(fields[i]) < kFieldSlot { return fmt.Errorf("missing field: %s [%d] [%d]", infos[i], len(fields[i]), kFieldSlot) } nodes[fields[i][kFieldAddr]] = &redisNode { name: fields[i][kFieldName], address: fields[i][kFieldAddr], slaves: make([]*redisNode, 0), connTimeout: cluster.connTimeout, readTimeout: cluster.readTimeout, writeTimeout: cluster.writeTimeout, keepAlive: cluster.keepAlive, aliveTime: cluster.aliveTime, } } ... }
the function well update the cluster info after connect to cluster, it Mainly process the cluster information returned by the cluster nodes command, and then get the address of each node
such as:
172.16.7.16:8001> cluster nodes 78a8926d4ad002e88f7d499ff4e590f6385b8ffd 172.16.7.16:8005@18005 slave 37a21de453a1118217fed1ec3535463d1bfe5244 0 1591076153884 4 connected 37a21de453a1118217fed1ec3535463d1bfe5244 172.16.7.16:8002@18002 master - 0 1591076151881 2 connected 5462-10922 f83fc4f5b61e4886be681e3b19b952781de9d1bc 172.16.7.16:8003@18003 master - 0 1591076152000 0 connected 10923-16383 b1a7ab40c42a0e8c9c5037aa3df7a701377567cd 172.16.7.16:8006@18006 slave f83fc4f5b61e4886be681e3b19b952781de9d1bc 0 1591076153000 5 connected 3e1c4883e904adde6c4e917c9929954cf14a1a57 172.16.7.16:8001@18001 myself,master - 0 1591076152000 1 connected 0-5461 4e6f4de2fab077ea612b05a4e264cb85a6a9eda7 172.16.7.16:8004@18004 slave 3e1c4883e904adde6c4e917c9929954cf14a1a57 0 1591076151000 3 connected
at this fields[i][kFieldAddr] is 172.16.7.16:8002@18002, so client run Do() well error, becase the address error
172.16.7.16:8002@18002
i modified as follows:
//github.com/chasex/redis-go-cluster@v1.0.0/cluster.go:622 for i := range fields { fields[i] = strings.Split(infos[i], " ") if len(fields[i]) < kFieldSlot { return fmt.Errorf("missing field: %s [%d] [%d]", infos[i], len(fields[i]), kFieldSlot) } //added by me: Handling the address field if strings.Contains(fields[i][kFieldAddr], "@") { fields[i][kFieldAddr] = strings.Split(fields[i][kFieldAddr], "@")[0] } nodes[fields[i][kFieldAddr]] = &redisNode { name: fields[i][kFieldName], address: fields[i][kFieldAddr], slaves: make([]*redisNode, 0), connTimeout: cluster.connTimeout, readTimeout: cluster.readTimeout, writeTimeout: cluster.writeTimeout, keepAlive: cluster.keepAlive, aliveTime: cluster.aliveTime, } }
or you can use the master, it had modify the way to updateClusterInfo:
cluster.go:314 func (cluster *Cluster) update(node *redisNode) error { info, err := Values(node.do("CLUSTER", "SLOTS")) .... }
redis version: redis-5.0.5 redis-go-cluster version: 1.0.0
my code
but when i go run, have this error
at last i find the code:
i find that, when panic happend, the node.address is "172.16.7.16:8002@18002"
but when is normal, the node.address is "172.16.7.16:8002"
so when run in debug mode, i modified it manually "172.16.7.16:8002@18002" to "172.16.7.16:8002", it is normal
one by one to follow the code call stack, i find that
the function well update the cluster info after connect to cluster, it Mainly process the cluster information returned by the cluster nodes command, and then get the address of each node
such as:
at this fields[i][kFieldAddr] is
172.16.7.16:8002@18002
, so client run Do() well error, becase the address errori modified as follows:
or you can use the master, it had modify the way to updateClusterInfo: