Akemi

k8s部署Redis高可用集群

2024/06/12

Redis概述

Redis是一个高性能的key-value数据库。

Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。有状态服务

Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。支持多数据结构

Redis支持数据的备份,即master-slave模式的数据备份。

Redis集群模式

主从模式

redis支持master-slave模式,一主多从,redis server可以设置另外多个redis server为slave,从机同步主机的数据。配置后,读写分离,主机负责读写服务,从机只负责读。减轻主机的压力。redis实现的是最终会一致性,具体选择强一致性还是弱一致性,取决于业务场景。

同步方式

redis 主从同步有两种方式(或者所两个阶段):全同步和部分同步。

刚连接全同步,后同步先尝试部分同步,如果不成功则使用全同步

主从刚刚连接的时候,进行全同步;全同步结束后,进行部分同步。当然,如果有需要,slave 在任何时候都可以发起全同步。

redis策略是,无论如何,首先会尝试进行部分同步,如不成功,要求从机进行全同步,并启动 BGSAVE……BGSAVE 结束后,传输 RDB 文件;如果成功,允许从机进行部分同步,并传输积压空间中的数据。简单来说,主从同步就是 RDB 文件的上传下载;主机有小部分的数据修改,就把修改记录传播给每个从机。

缺点:如果主节点发生故障,整个系统将无法写入新的数据,尽管从节点可以继续处理读操作。这意味着,一旦主节点宕机,系统将无法接收任何写请求,直到主节点恢复或故障转移完成。

redis Sentinel(哨兵)模式

是用于监控Redis集群中Master状态的工具,是Redis高可用解决方案,哨兵可以监视一个或者多个redis master服务,以及这些master服务的所有从服务。 某个master服务宕机后,会把这个master下的某个从服务升级为master来替代已宕机的master继续工作。

优点:高可用性,自动故障转移,支持多个哨兵节点,提高了系统的容错能力和稳定性

缺点:资源占用、配置复杂和扩容困难

Redis-cluster集群模式

redis集群技术是构建高性能网站架构的重要手段,Redis Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。节点之间使用gossip协议传播信息以及发现新节点。

Redis 集群是一个分布式(distributed)、容错(fault-tolerant)的 Redis 实现,集群可以使用的功能是普通单机 Redis 所能使用的功能的一个子集(subset)。

具备线性可扩展性(linear scalability)。

Redis 集群为了保证一致性(consistency)而牺牲了一部分容错性:系统会在保证对网络断线和节点失效具有有限抵抗力的前提下,尽可能地保持数据的一致性

Redis-Cluster集群模式部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
1.准备存储,这里用的是nfs
供应商为example.com/nfs,存储类名称nfs

2.创建无头服务,因为用的是statefulset,不需要指定特定的pod
apiVersion: v1
kind: Service
metadata:
name: redis-service
labels:
app: redis
spec:
ports:
- name: redis-port
port: 6379
clusterIP: None
selector:
app: redis
appCluster: redis-cluster

3.创建Redis的config配置文件
vim conf-redis.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: redis-conf
data:
redis.conf: |
appendonly yes
cluster-enabled yes
cluster-config-file /var/lib/redis/nodes.conf
cluster-node-timeout 5000
dir /var/lib/redis
port 6379

4.使用statefulset创建Redis Cluster
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-app
spec:
serviceName: "redis-service"
replicas: 6
selector:
matchLabels:
app: redis
appCluster: redis-cluster
template:
metadata:
labels:
app: redis
appCluster: redis-cluster
spec:
containers:
- name: redis
image: redis
imagePullPolicy: IfNotPresent
command:
- "redis-server"
args:
- "/etc/redis/redis.conf"
- "--protected-mode"
- "no"
resources:
requests:
cpu: "100m"
memory: "100Mi"
ports:
- name: redis
containerPort: 6379
protocol: "TCP"
- name: cluster
containerPort: 16379
protocol: "TCP"
volumeMounts:
- name: "redis-conf"
mountPath: "/etc/redis"
- name: "redis-data"
mountPath: "/var/lib/redis"
volumes:
- name: "redis-conf"
configMap:
name: "redis-conf"
items:
- key: "redis.conf"
path: "redis.conf"
volumeClaimTemplates:
- metadata:
name: redis-data
spec:
accessModes: [ "ReadWriteMany" ]
storageClassName: nfs
resources:
requests:
storage: 500M

kubectl apply -f svc-redis.yaml -f redis.yaml

kubectl get pods
NAME READY STATUS RESTARTS AGE
nfs-provisioner-bd5ddfb84-fvbzr 1/1 Running 2 (8d ago) 8d
redis-app-0 1/1 Running 0 85s
redis-app-1 1/1 Running 0 81s
redis-app-2 1/1 Running 0 77s
redis-app-3 1/1 Running 0 74s
redis-app-4 1/1 Running 0 70s
redis-app-5 1/1 Running 0 66s

测试dns:
kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox -- sh
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name: redis-app-0.redis-service.default.svc.cluster.local
Address 1: 10.244.193.156 redis-app-0.redis-service.default.svc.cluster.local

5.初始化redis集群
(1)安装工具
创建一个ubuntu容器
redis-tribe工具,主要在redis3和redis4中使用,在redis5中被废弃,依赖于python2
redis-cli工具,在redis4和redis5以后的版本中使用,依赖于python3

kubectl run -it ubuntu --image=ubuntu --image-pull-policy=IfNotPresent \
--restart=Never /bin/bash
# 懒得修改源了,直接下软件吧
apt-get update
apt-get install -y vim wget python3-pip redis-tools dnsutils
apt install python3-redis
#Setting up python3-async-timeout (4.0.3-1) ...
#Setting up python3-packaging (24.0-1) ...
#Setting up python3-wrapt (1.15.0-2build3) ...
#Setting up python3-deprecated (1.2.14-1) ...
#Setting up python3-redis (4.3.4-3) ...

(2)创建master节点
dig +short redis-app-0.redis-service.default.svc.cluster.local
10.244.193.156
dig +short redis-app-1.redis-service.default.svc.cluster.local
10.244.179.53
dig +short redis-app-2.redis-service.default.svc.cluster.local
10.244.234.81

redis-trib.py create 10.244.193.156:6379 10.244.179.53:6379 10.244.234.81:6379

redis-cli --cluster create 10.244.193.156:6379 10.244.179.53:6379 10.244.234.81:6379 --cluster-replicas 0

(3)查看master节点
redis-cli -c -h 10.244.193.156 -p 6379 # 连接到集群
CLUSTER NODES
58adaf3a638a4103ff7c80cbf474214df80bf3da 10.244.234.81:6379@16379 master - 0 1718129709263 3 connected 10923-16383
d46aa93dcc7b54ce4d03e987cab9757e008e131c 10.244.179.53:6379@16379 master - 0 1718129708258 2 connected 5461-10922
7177c0b6de3e8fe014f92138345addc1c5dd01d3 10.244.193.156:6379@16379 myself,master - 0 1718129707000 1 connected 0-5460
前面那一串就是master节点的id

(4)从节点加入集群
加入之后默认会变成主节点
dig +short redis-app-3.redis-service.default.svc.cluster.local
10.244.193.155
dig +short redis-app-4.redis-service.default.svc.cluster.local
10.244.179.3
dig +short redis-app-5.redis-service.default.svc.cluster.local
10.244.234.124

redis-cli --cluster add-node <new_host>:<new_port> existing_host:existing_port
redis-cli --cluster add-node 10.244.193.155:6379 10.244.193.156:6379
redis-cli --cluster add-node 10.244.179.3:6379 10.244.193.156:6379
redis-cli --cluster add-node 10.244.234.124:6379 10.244.193.156:6379

redis-cli --cluster create和 add-node 的区别:
redis-cli --cluster create 命令初始化集群
redis-cli --cluster add-node 命令将一个新的节点添加到集群中

(5)给每个master添加slave

redis-cli -h <slave-ip> -p <slave-port> CLUSTER REPLICATE <master-node-id>
redis-cli -h 10.244.193.155 -p 6379 CLUSTER REPLICATE 7177c0b6de3e8fe014f92138345addc1c5dd01d3
redis-cli -h 10.244.179.3 -p 6379 CLUSTER REPLICATE d46aa93dcc7b54ce4d03e987cab9757e008e131c
redis-cli -h 10.244.234.124 -p 6379 CLUSTER REPLICATE 58adaf3a638a4103ff7c80cbf474214df80bf3da

查看状态:
CLUSTER NODES
f3fe68dfd711b0338fe50687357a1e83fcbae519 10.244.234.124:6379@16379 slave 58adaf3a638a4103ff7c80cbf474214df80bf3da 0 1718158690827 3 connected
d46aa93dcc7b54ce4d03e987cab9757e008e131c 10.244.179.53:6379@16379 master - 0 1718158690000 2 connected 5461-10922
794e4d6387579be9a9d5dd4f9e7e44bf635034c0 10.244.193.155:6379@16379 slave 7177c0b6de3e8fe014f92138345addc1c5dd01d3 0 1718158690000 1 connected
c8149fb053bd54feeae4848321182725aec003bf 10.244.179.3:6379@16379 slave d46aa93dcc7b54ce4d03e987cab9757e008e131c 0 1718158690526 2 connected
58adaf3a638a4103ff7c80cbf474214df80bf3da 10.244.234.81:6379@16379 master - 0 1718158690526 3 connected 10923-16383
7177c0b6de3e8fe014f92138345addc1c5dd01d3 10.244.193.156:6379@16379 myself,master - 0 1718158690000 1 connected 0-5460

cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:5
cluster_my_epoch:1
cluster_stats_messages_ping_sent:32968
cluster_stats_messages_pong_sent:32147
cluster_stats_messages_sent:65115
cluster_stats_messages_ping_received:32142
cluster_stats_messages_pong_received:32968
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:65115
total_cluster_links_buffer_limit_exceeded:0

(6)添加一个用以访问的service
apiVersion: v1
kind: Service
metadata:
name: redis-access-service
labels:
app: redis
spec:
ports:
- name: redis-port
protocol: "TCP"
port: 6379
targetPort: 6379
selector:
app: redis
appCluster: redis-cluster
CATALOG
  1. 1. Redis概述
  2. 2. Redis集群模式
    1. 2.1. 主从模式
    2. 2.2. redis Sentinel(哨兵)模式
    3. 2.3. Redis-cluster集群模式
  3. 3. Redis-Cluster集群模式部署