Skip to content

Commit b43f643

Browse files
committed
fixed: generate configmap for redis to start from /conf/redis.conf; force set appendonly=no when do restore
1 parent 99ea19c commit b43f643

File tree

6 files changed

+315
-2
lines changed

6 files changed

+315
-2
lines changed

pkg/controller/distributedrediscluster/sync_handler.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ func (r *ReconcileDistributedRedisCluster) ensureCluster(ctx *syncContext) error
3636
}
3737
return StopRetry.Wrap(err, "stop retry")
3838
}
39+
40+
// Redis only load db from append only file when AOF ON, because of
41+
// we only backed up the RDB file when doing data backup, so we set
42+
// "appendonly no" force here when do restore.
43+
dbLoadedFromDiskWhenRestore(cluster, ctx.reqLogger)
3944
labels := getLabels(cluster)
4045
if err := r.ensurer.EnsureRedisConfigMap(cluster, labels); err != nil {
4146
return Kubernetes.Wrap(err, "EnsureRedisConfigMap")
@@ -98,9 +103,19 @@ func (r *ReconcileDistributedRedisCluster) validate(cluster *redisv1alpha1.Distr
98103
if update || updateDefault {
99104
return r.crController.UpdateCR(cluster)
100105
}
106+
101107
return nil
102108
}
103109

110+
func dbLoadedFromDiskWhenRestore(cluster *redisv1alpha1.DistributedRedisCluster, reqLogger logr.Logger) {
111+
if cluster.IsRestoreFromBackup() && !cluster.IsRestored() {
112+
if cluster.Spec.Config != nil {
113+
reqLogger.Info("force appendonly = no when do restore")
114+
cluster.Spec.Config["appendonly"] = "no"
115+
}
116+
}
117+
}
118+
104119
func (r *ReconcileDistributedRedisCluster) validateRestore(cluster *redisv1alpha1.DistributedRedisCluster, reqLogger logr.Logger) (bool, error) {
105120
update := false
106121
if cluster.Status.Restore.Backup == nil {

pkg/controller/manager/ensurer.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package manager
22

33
import (
44
"strconv"
5+
"strings"
56

67
"github.com/go-logr/logr"
78
appsv1 "k8s.io/api/apps/v1"
@@ -189,7 +190,7 @@ func (r *realEnsureResource) EnsureRedisSvc(cluster *redisv1alpha1.DistributedRe
189190

190191
func (r *realEnsureResource) EnsureRedisConfigMap(cluster *redisv1alpha1.DistributedRedisCluster, labels map[string]string) error {
191192
cmName := configmaps.RedisConfigMapName(cluster.Name)
192-
_, err := r.configMapClient.GetConfigMap(cluster.Namespace, cmName)
193+
drcCm, err := r.configMapClient.GetConfigMap(cluster.Namespace, cmName)
193194
if err != nil {
194195
if errors.IsNotFound(err) {
195196
r.logger.WithValues("ConfigMap.Namespace", cluster.Namespace, "ConfigMap.Name", cmName).
@@ -201,6 +202,13 @@ func (r *realEnsureResource) EnsureRedisConfigMap(cluster *redisv1alpha1.Distrib
201202
} else {
202203
return err
203204
}
205+
} else {
206+
if isRedisConfChanged(drcCm.Data[configmaps.RedisConfKey], cluster.Spec.Config, r.logger) {
207+
cm := configmaps.NewConfigMapForCR(cluster, labels)
208+
if err2 := r.configMapClient.UpdateConfigMap(cm); err2 != nil {
209+
return err2
210+
}
211+
}
204212
}
205213

206214
if cluster.IsRestoreFromBackup() {
@@ -237,3 +245,26 @@ func (r *realEnsureResource) EnsureRedisOSMSecret(cluster *redisv1alpha1.Distrib
237245
}
238246
return nil
239247
}
248+
249+
func isRedisConfChanged(confInCm string, currentConf map[string]string, log logr.Logger) bool {
250+
lines := strings.Split(strings.TrimSuffix(confInCm, "\n"), "\n")
251+
if len(lines) != len(currentConf) {
252+
return true
253+
}
254+
for _, line := range lines {
255+
line = strings.TrimSuffix(line, " ")
256+
confLine := strings.SplitN(line, " ", 2)
257+
if len(confLine) == 2 {
258+
if valueInCurrentConf, ok := currentConf[confLine[0]]; !ok {
259+
return true
260+
} else {
261+
if valueInCurrentConf != confLine[1] {
262+
return true
263+
}
264+
}
265+
} else {
266+
log.Info("custom config is invalid", "raw", line, "split", confLine)
267+
}
268+
}
269+
return false
270+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package manager
2+
3+
import (
4+
"testing"
5+
6+
"github.com/go-logr/logr"
7+
logf "sigs.k8s.io/controller-runtime/pkg/log"
8+
)
9+
10+
var log = logf.Log.WithName("test")
11+
12+
func Test_isRedisConfChanged(t *testing.T) {
13+
type args struct {
14+
confInCm string
15+
currentConf map[string]string
16+
log logr.Logger
17+
}
18+
tests := []struct {
19+
name string
20+
args args
21+
want bool
22+
}{
23+
{
24+
name: "should false",
25+
args: args{
26+
confInCm: `appendfsync everysec
27+
appendonly yes
28+
auto-aof-rewrite-min-size 67108864
29+
save 900 1 300 10`,
30+
currentConf: map[string]string{
31+
"appendfsync": "everysec",
32+
"appendonly": "yes",
33+
"auto-aof-rewrite-min-size": "67108864",
34+
"save": "900 1 300 10",
35+
},
36+
log: log,
37+
},
38+
want: false,
39+
},
40+
{
41+
name: "should false with newline",
42+
args: args{
43+
confInCm: `appendfsync everysec
44+
appendonly yes
45+
auto-aof-rewrite-min-size 67108864
46+
save 900 1 300 10
47+
`,
48+
currentConf: map[string]string{
49+
"appendfsync": "everysec",
50+
"appendonly": "yes",
51+
"auto-aof-rewrite-min-size": "67108864",
52+
"save": "900 1 300 10",
53+
},
54+
log: log,
55+
},
56+
want: false,
57+
},
58+
{
59+
name: "should true, compare value",
60+
args: args{
61+
confInCm: `appendfsync everysec
62+
appendonly yes
63+
auto-aof-rewrite-min-size 6710886
64+
save 900 1 300 10
65+
`,
66+
currentConf: map[string]string{
67+
"appendfsync": "everysec",
68+
"appendonly": "yes",
69+
"auto-aof-rewrite-min-size": "67108864",
70+
"save": "900 1 300 10",
71+
},
72+
log: log,
73+
},
74+
want: true,
75+
},
76+
{
77+
name: "should true, add current",
78+
args: args{
79+
confInCm: `appendfsync everysec
80+
appendonly yes
81+
save 900 1 300 10
82+
`,
83+
currentConf: map[string]string{
84+
"appendfsync": "everysec",
85+
"appendonly": "yes",
86+
"auto-aof-rewrite-min-size": "67108864",
87+
"save": "900 1 300 10",
88+
},
89+
log: log,
90+
},
91+
want: true,
92+
},
93+
{
94+
name: "should true, del current",
95+
args: args{
96+
confInCm: `appendfsync everysec
97+
appendonly yes
98+
auto-aof-rewrite-min-size 67108864
99+
save 900 1 300 10
100+
`,
101+
currentConf: map[string]string{
102+
"appendfsync": "everysec",
103+
"appendonly": "yes",
104+
"save": "900 1 300 10",
105+
},
106+
log: log,
107+
},
108+
want: true,
109+
},
110+
{
111+
name: "should true, compare key",
112+
args: args{
113+
confInCm: `appendfsync everysec
114+
appendonly yes
115+
save 900 1 300 10
116+
`,
117+
currentConf: map[string]string{
118+
"appendonly": "yes",
119+
"auto-aof-rewrite-min-size": "67108864",
120+
"save": "900 1 300 10",
121+
},
122+
log: log,
123+
},
124+
want: true,
125+
},
126+
{
127+
name: "should true, compare save",
128+
args: args{
129+
confInCm: `appendfsync everysec
130+
appendonly yes
131+
auto-aof-rewrite-min-size 67108864
132+
save 900 1 300 10
133+
`,
134+
currentConf: map[string]string{
135+
"appendfsync": "everysec",
136+
"appendonly": "yes",
137+
"auto-aof-rewrite-min-size": "67108864",
138+
"save": "900 1",
139+
},
140+
log: log,
141+
},
142+
want: true,
143+
},
144+
}
145+
for _, tt := range tests {
146+
t.Run(tt.name, func(t *testing.T) {
147+
if got := isRedisConfChanged(tt.args.confInCm, tt.args.currentConf, tt.args.log); got != tt.want {
148+
t.Errorf("isRedisConfChanged() = %v, want %v", got, tt.want)
149+
}
150+
})
151+
}
152+
}

pkg/resources/configmaps/configmap.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
package configmaps
22

33
import (
4+
"bytes"
45
"fmt"
6+
"sort"
57

68
corev1 "k8s.io/api/core/v1"
79
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
810

911
redisv1alpha1 "github.com/ucloud/redis-cluster-operator/pkg/apis/redis/v1alpha1"
1012
)
1113

12-
const RestoreSucceeded = "succeeded"
14+
const (
15+
RestoreSucceeded = "succeeded"
16+
17+
RedisConfKey = "redis.conf"
18+
)
1319

1420
// NewConfigMapForCR creates a new ConfigMap for the given Cluster
1521
func NewConfigMapForCR(cluster *redisv1alpha1.DistributedRedisCluster, labels map[string]string) *corev1.ConfigMap {
@@ -45,6 +51,8 @@ if [ -f ${CLUSTER_CONFIG} ]; then
4551
fi
4652
exec "$@"`
4753

54+
redisConfContent := generateRedisConfContent(cluster.Spec.Config)
55+
4856
return &corev1.ConfigMap{
4957
ObjectMeta: metav1.ObjectMeta{
5058
Name: RedisConfigMapName(cluster.Name),
@@ -55,10 +63,32 @@ exec "$@"`
5563
Data: map[string]string{
5664
"shutdown.sh": shutdownContent,
5765
"fix-ip.sh": fixIPContent,
66+
RedisConfKey: redisConfContent,
5867
},
5968
}
6069
}
6170

71+
func generateRedisConfContent(configMap map[string]string) string {
72+
if configMap == nil {
73+
return ""
74+
}
75+
76+
var buffer bytes.Buffer
77+
78+
keys := make([]string, 0, len(configMap))
79+
for k := range configMap {
80+
keys = append(keys, k)
81+
}
82+
sort.Strings(keys)
83+
84+
for _, k := range keys {
85+
buffer.WriteString(fmt.Sprintf("%s %s", k, configMap[k]))
86+
buffer.WriteString("\n")
87+
}
88+
89+
return buffer.String()
90+
}
91+
6292
func RedisConfigMapName(clusterName string) string {
6393
return fmt.Sprintf("%s-%s", "redis-cluster", clusterName)
6494
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package configmaps
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func Test_generateRedisConfContent(t *testing.T) {
8+
confMap := map[string]string{
9+
"activerehashing": "yes",
10+
"appendfsync": "everysec",
11+
"appendonly": "yes",
12+
"auto-aof-rewrite-min-size": "67108864",
13+
"auto-aof-rewrite-percentage": "100",
14+
"cluster-node-timeout": "15000",
15+
"cluster-require-full-coverage": "yes",
16+
"hash-max-ziplist-entries": "512",
17+
"hash-max-ziplist-value": "64",
18+
"hll-sparse-max-bytes": "3000",
19+
"list-compress-depth": "0",
20+
"maxmemory": "1000000000",
21+
"maxmemory-policy": "noeviction",
22+
"maxmemory-samples": "5",
23+
"no-appendfsync-on-rewrite": "no",
24+
"notify-keyspace-events": "",
25+
"repl-backlog-size": "1048576",
26+
"repl-backlog-ttl": "3600",
27+
"set-max-intset-entries": "512",
28+
"slowlog-log-slower-than": "10000",
29+
"slowlog-max-len": "128",
30+
"stop-writes-on-bgsave-error": "yes",
31+
"tcp-keepalive": "0",
32+
"timeout": "0",
33+
"zset-max-ziplist-entries": "128",
34+
"zset-max-ziplist-value": "64",
35+
}
36+
want := `activerehashing yes
37+
appendfsync everysec
38+
appendonly yes
39+
auto-aof-rewrite-min-size 67108864
40+
auto-aof-rewrite-percentage 100
41+
cluster-node-timeout 15000
42+
cluster-require-full-coverage yes
43+
hash-max-ziplist-entries 512
44+
hash-max-ziplist-value 64
45+
hll-sparse-max-bytes 3000
46+
list-compress-depth 0
47+
maxmemory 1000000000
48+
maxmemory-policy noeviction
49+
maxmemory-samples 5
50+
no-appendfsync-on-rewrite no
51+
notify-keyspace-events
52+
repl-backlog-size 1048576
53+
repl-backlog-ttl 3600
54+
set-max-intset-entries 512
55+
slowlog-log-slower-than 10000
56+
slowlog-max-len 128
57+
stop-writes-on-bgsave-error yes
58+
tcp-keepalive 0
59+
timeout 0
60+
zset-max-ziplist-entries 128
61+
zset-max-ziplist-value 64
62+
`
63+
type args struct {
64+
configMap map[string]string
65+
}
66+
tests := []struct {
67+
name string
68+
args args
69+
want string
70+
}{
71+
{
72+
name: "test",
73+
args: struct{ configMap map[string]string }{configMap: confMap},
74+
want: want,
75+
},
76+
}
77+
for _, tt := range tests {
78+
t.Run(tt.name, func(t *testing.T) {
79+
if got := generateRedisConfContent(tt.args.configMap); got != tt.want {
80+
t.Errorf("generateRedisConfContent()\n[%v], want\n[%v]", got, tt.want)
81+
}
82+
})
83+
}
84+
}

0 commit comments

Comments
 (0)