Skip to content

Commit 78b14d0

Browse files
authored
Merge pull request #8 from ucloud/feature/fake_slave
feature: ignore slave whose slave-priority = 0
2 parents f4cf6ef + 1bd62d6 commit 78b14d0

File tree

3 files changed

+94
-12
lines changed

3 files changed

+94
-12
lines changed

pkg/apis/redis/v1beta1/validate.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ const (
1414
defaultRedisNumber = 3
1515
defaultSentinelNumber = 3
1616
defaultRedisImage = "redis:5.0.4-alpine"
17+
18+
defaultSlavePriority = "1"
1719
)
1820

1921
var (
@@ -29,7 +31,7 @@ func (r *RedisCluster) Validate() error {
2931
if r.Spec.Size == 0 {
3032
r.Spec.Size = defaultRedisNumber
3133
} else if r.Spec.Size < defaultRedisNumber {
32-
return errors.New("number of redises in spec is less than the minimum")
34+
return errors.New("number of redis in spec is less than the minimum")
3335
}
3436

3537
if r.Spec.Sentinel.Replicas == 0 {
@@ -54,6 +56,9 @@ func (r *RedisCluster) Validate() error {
5456
r.Spec.Config = make(map[string]string)
5557
}
5658

59+
// https://github.com/ucloud/redis-operator/issues/6
60+
r.Spec.Config["slave-priority"] = defaultSlavePriority
61+
5762
if !r.Spec.DisablePersistence {
5863
enablePersistence(r.Spec.Config)
5964
} else {

pkg/client/redis/client.go

+28-7
Original file line numberDiff line numberDiff line change
@@ -92,20 +92,41 @@ func (c *client) GetNumberSentinelSlavesInMemory(ip string, auth *util.AuthConfi
9292
return 0, err
9393
}
9494

95-
if err2 := isSentinelReady(info); err2 != nil {
96-
return 0, err2
97-
}
98-
match := slaveNumberRE.FindStringSubmatch(info)
99-
if len(match) == 0 {
100-
return 0, errors.New("slaves regex not found")
95+
if err = isSentinelReady(info); err != nil {
96+
return 0, err
10197
}
102-
nSlaves, err := strconv.Atoi(match[1])
98+
99+
cmd := rediscli.NewSliceCmd("sentinel", "slaves", masterName)
100+
rClient.Process(cmd)
101+
slaveInfoBlobs, err := cmd.Result()
103102
if err != nil {
104103
return 0, err
105104
}
105+
nSlaves := len(slaveInfoBlobs)
106+
for _, slaveInfoBlob := range slaveInfoBlobs {
107+
slavePriority := slaveInfoFieldByName("slave-priority", slaveInfoBlob)
108+
if slavePriority == "0" {
109+
nSlaves -= 1
110+
}
111+
}
112+
106113
return int32(nSlaves), nil
107114
}
108115

116+
func slaveInfoFieldByName(name string, slaveInfoBlob interface{}) string {
117+
slaveInfo := slaveInfoBlob.([]interface{})
118+
infoLens := len(slaveInfo)
119+
i := 0
120+
for i+1 < infoLens {
121+
stringValue := slaveInfo[i].(string)
122+
if stringValue == name {
123+
return slaveInfo[i+1].(string)
124+
}
125+
i += 2
126+
}
127+
return ""
128+
}
129+
109130
func isSentinelReady(info string) error {
110131
matchStatus := sentinelStatusRE.FindStringSubmatch(info)
111132
if len(matchStatus) == 0 || matchStatus[1] != "ok" {

pkg/client/redis/client_test.go

+60-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
package redis_test
1+
package redis
22

33
import (
4-
rediscli "github.com/go-redis/redis"
5-
"github.com/ucloud/redis-operator/pkg/client/redis"
64
"strings"
75
"testing"
6+
7+
rediscli "github.com/go-redis/redis"
88
)
99

1010
func newClient() *rediscli.Client {
@@ -18,7 +18,7 @@ func newClient() *rediscli.Client {
1818
func TestGetAllRedisConfig(t *testing.T) {
1919
cli := newClient()
2020
//var client redis.Client
21-
client := redis.New()
21+
client := New()
2222
result, err := client.GetAllRedisConfig(cli)
2323
if err != nil {
2424
t.Fatal(err)
@@ -33,3 +33,59 @@ func TestGetAllRedisConfig(t *testing.T) {
3333
}
3434

3535
}
36+
37+
func Test_slaveInfoFieldByName(t *testing.T) {
38+
slaveInfoBlobA := []interface{}{"name", "[xxxxA]:6379", "ip", "xxxxA", "port", "6379", "runid", "6f792839ab551e8dbec58e0eb3b3838d14f19a37", "flags", "slave", "link-pending-commands", "1", "link-refcount", "1", "last-ping-sent", "0", "last-ok-ping-reply", "1055", "last-ping-reply", "1055", "down-after-milliseconds", "5000", "info-refresh", "2074", "role-reported", "slave", "role-reported-time", "2983115", "master-link-down-time", "0", "master-link-status", "ok", "master-host", "xxxxA", "master-port", "6379", "slave-priority", "1", "slave-repl-offset", "124614695"}
39+
slaveInfoBlobB := []interface{}{"name", "[xxxxB]:6371", "ip", "xxxxB", "port", "6371", "runid", "fake_slave_8bb90711-8f37-44e8-b3b2-589af", "flags", "slave", "link-pending-commands", "1", "link-refcount", "1", "last-ping-sent", "0", "last-ok-ping-reply", "1055", "last-ping-reply", "1055", "down-after-milliseconds", "5000", "info-refresh", "2075", "role-reported", "slave", "role-reported-time", "2983114", "master-link-down-time", "0", "master-link-status", "ok", "master-host", "xxxxB", "master-port", "6379", "slave-priority", "0", "slave-repl-offset", "124614695"}
40+
slaveInfoBlobC := []interface{}{"name", "[xxxxB]:6371", "ip", "slave-priority", "slave-priority", "100"}
41+
slaveInfoBlobD := []interface{}{"name", "[xxxxB]:6371", "ip", "xxxxB", "slave-priority"}
42+
type args struct {
43+
name string
44+
slaveInfoBlob interface{}
45+
}
46+
tests := []struct {
47+
name string
48+
args args
49+
want string
50+
}{
51+
{
52+
name: "slaveA",
53+
args: args{
54+
name: "slave-priority",
55+
slaveInfoBlob: slaveInfoBlobA,
56+
},
57+
want: "1",
58+
},
59+
{
60+
name: "slaveB",
61+
args: args{
62+
name: "slave-priority",
63+
slaveInfoBlob: slaveInfoBlobB,
64+
},
65+
want: "0",
66+
},
67+
{
68+
name: "slaveC",
69+
args: args{
70+
name: "slave-priority",
71+
slaveInfoBlob: slaveInfoBlobC,
72+
},
73+
want: "100",
74+
},
75+
{
76+
name: "slaveD",
77+
args: args{
78+
name: "slave-priority",
79+
slaveInfoBlob: slaveInfoBlobD,
80+
},
81+
want: "",
82+
},
83+
}
84+
for _, tt := range tests {
85+
t.Run(tt.name, func(t *testing.T) {
86+
if got := slaveInfoFieldByName(tt.args.name, tt.args.slaveInfoBlob); got != tt.want {
87+
t.Errorf("slaveInfoFieldByName() = %v, want %v", got, tt.want)
88+
}
89+
})
90+
}
91+
}

0 commit comments

Comments
 (0)