专栏首页千里行走kubernetes-20:redis-cluster容器化

kubernetes-20:redis-cluster容器化

目录:

(1).redis容器化

1.容器化redis-cluster各个节点实例

2.初始化redis-cluster集群

3.集群节点文件说明

3.1.appendonly.aof

3.2.dump.rdb

3.3.PDB和AOF的优先级

3.4.nodes.conf

(2).容器重启导致节点ip变化的问题解决

2.1.相关配置方式

2.2.整个操作过程演示

2.3.应用如何适配

(3).配置文件说明

(4).相关文章阅读

笔者使用Redis容器化只用于本地环境,用于自己一些项目的调试(https://github.com/hepyu/saf)。

故,是一个简单实现,pod亲和性等生产级别配置没有做过多考虑。

如果要生产环境容器化redis,需要考虑方方面面的问题,很长的一个过程。

(1).redis容器化

1.容器化redis-cluster各个节点实例

先执行local pv所使用的本地pv目录:

https://github.com/hepyu/k8s-app-config/blob/master/yaml/init.sh

执行命令容器化redis-cluster:sh ./deploy.sh

查看redis容器化节点实例

kubectl get all -n redis-cluster-min -o wide

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES

pod/redis-hkc-0 1/1 Running 0 8d 10.244.0.108 future <none> <none>

pod/redis-hkc-1 1/1 Running 0 8d 10.244.0.109 future <none> <none>

pod/redis-hkc-2 1/1 Running 0 8d 10.244.0.110 future <none> <none>

pod/redis-hkc-3 1/1 Running 0 8d 10.244.0.111 future <none> <none>

pod/redis-hkc-4 1/1 Running 0 8d 10.244.0.112 future <none> <none>

pod/redis-hkc-5 1/1 Running 0 8d 10.244.0.113 future <none> <none>

接下来我们要做redis集群初始化,如果我们现在进入redis操作会出现什么情况呢?

我们进入其中的一个redis node中执行set, get尝试操作,会提示错误:

root@redis-hkc-0:/data# redis-cli -h 10.244.0.111 -p 9720 -c

10.244.0.111:9720>

10.244.0.111:9720> cluster info

cluster_state:fail

cluster_slots_assigned:16384

cluster_slots_ok:5461

cluster_slots_pfail:10923

cluster_slots_fail:0

cluster_known_nodes:6

cluster_size:3

cluster_current_epoch:6

cluster_my_epoch:3

cluster_stats_messages_ping_sent:1154655

cluster_stats_messages_sent:1154655

cluster_stats_messages_received:0

10.244.0.111:9720>

10.244.0.111:9720>

10.244.0.111:9720>

10.244.0.111:9720> set a 1

(error) CLUSTERDOWN The cluster is down

可以看到cluster info是可以显示cluster的信息,但是执行set/get方法时提示cluster down,这是因为我们没有完成redis-cluster的初始化。

2.初始化redis-cluster集群

我们再开一个容器进行此项操作,为此我专门制作了一个image专门用于进行redis-cluster初始化,工程位于:

https://github.com/hepyu/redis-cluster-initialize-image

(需要注意,我用的redis版本是5.x)。

git clone 后直接执行docker.build.sh完成image制作。

执行命令进入容器

kubectl run -i --tty init-redis-cluster --image=hpy253215039/redis-cluster-initialize-image:0.1 --restart=Never /bin/bash

(第二次进入执行:kubectl exec -it init-redis-cluster -- /bin/bash)

进入容器后,cd /app/3rd/redis-5.0.7/src,执行:

Redis-5.0已经舍弃了redis-trib.py的方式初始化集群,改用redis-cli初始化集群:

redis-cli --cluster create --cluster-replicas 1 10.244.0.173:9720 10.244.0.109:9720 10.244.0.110:9720 10.244.0.111:9720 10.244.0.112:9720 10.244.0.113:9720

有可能会报错:

Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

解决方式:

1)、将需要新增的节点下aof、rdb等本地备份文件删除;

2)、同时将新Node的集群配置文件删除,即:删除你redis.conf里面cluster-config-file所在的文件;

3)、再次添加新节点如果还是报错,则登录新Node,./redis-cli–h x –p对数据库进行清除:

Ip:7001> flushdb #清空当前数据库

我图省事(自己用嘛),直接删除local pv重建目录,重新容器化。

redis-cli --cluster create --cluster-replicas 1 10.244.0.184:9720 10.244.0.185:9720 10.244.0.186:9720 10.244.0.187:9720 10.244.0.188:9720 10.244.0.189:9720

可以发现IP发生变化,打印信息:

>>> Performing hash slots allocation on 6 nodes...

Master[0] -> Slots 0 - 5460

Master[1] -> Slots 5461 - 10922

Master[2] -> Slots 10923 - 16383

Adding replica 10.244.0.188:9720 to 10.244.0.184:9720

Adding replica 10.244.0.189:9720 to 10.244.0.185:9720

Adding replica 10.244.0.187:9720 to 10.244.0.186:9720

M: f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.184:9720

slots:[0-5460] (5461 slots) master

M: 150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720

slots:[5461-10922] (5462 slots) master

M: a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720

slots:[10923-16383] (5461 slots) master

S: 3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.187:9720

replicates a44ee1eaef7f89cd1013f10638d5d878dd982001

S: 699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720

replicates f8b4cc1d884eb3ced239c572e016a49cabd0313f

S: 3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720

replicates 150da7a79af740c55a61124f1d422fb9fcd19459

Can I set the above configuration? (type 'yes' to accept): yes

>>> Nodes configuration updated

>>> Assign a different config epoch to each node

>>> Sending CLUSTER MEET messages to join the cluster

Waiting for the cluster to join

......

>>> Performing Cluster Check (using node 10.244.0.184:9720)

M: f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.184:9720

slots:[0-5460] (5461 slots) master

1 additional replica(s)

S: 3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720

slots: (0 slots) slave

replicates 150da7a79af740c55a61124f1d422fb9fcd19459

S: 699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720

slots: (0 slots) slave

replicates f8b4cc1d884eb3ced239c572e016a49cabd0313f

M: 150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720

slots:[5461-10922] (5462 slots) master

1 additional replica(s)

S: 3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.187:9720

slots: (0 slots) slave

replicates a44ee1eaef7f89cd1013f10638d5d878dd982001

M: a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720

slots:[10923-16383] (5461 slots) master

1 additional replica(s)

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

我们使用命令行进入其中的一个节点:

[root@init-redis-cluster redis-5.0.7]# redis-cli -c -h 10.244.0.184 -p 9720

10.244.0.184:9720> get a 1

(error) ERR wrong number of arguments for 'get' command

10.244.0.184:9720> 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:6

cluster_my_epoch:1

cluster_stats_messages_ping_sent:160

cluster_stats_messages_pong_sent:150

cluster_stats_messages_sent:310

cluster_stats_messages_ping_received:145

cluster_stats_messages_pong_received:160

cluster_stats_messages_meet_received:5

cluster_stats_messages_received:310

10.244.0.184:9720>

10.244.0.184:9720>

10.244.0.184:9720> set a 1

-> Redirected to slot [15495] located at 10.244.0.186:9720

OK

10.244.0.186:9720> get a

"1"

10.244.0.186:9720>

可以看到,集群现在处于可用状态。

3.集群节点文件说明

我们随意找一个本地存储:/datavip/k8s-data/redis-cluster-min-pv-local-0,其目录结构如下:

appendonly.aof

dump.rdb

nodes.conf

3.1.appendonly.aof

以日志的形式来记录每个写操作,将redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

这也是为什么我们在使用redis时会有一些禁手,比如:不允许用keys等操作,因为其执行时间的方差差异太大,有可能直接把整个集群堵死。笔者曾经工作的一家公司,有同学用keys,直接把redis-cluster生产集群的tps干到<1。

3.2.dump.rdb

指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际的操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储(binlog)。存储的文件为:dum.rdb

RDB需要fork子进程来进行持久化。如果数据集太大,fork系统调用可能消耗较多时间,甚至导致redis暂停服务( n ms-1s)。AOF也需要fork,但是你可以在不影响持久性的前提下控制多久重写一次日志。

3.3.PDB和AOF的优先级

Redis 4.0 之后新增的方式,混合持久化(同时开启RDB和AOF模式),是结合了 RDB 和 AOF 的优点,在写入的时候,先把当前的数据以 RDB 的形式写入文件的开头,再将后续的操作命令以 AOF 的格式存入文件,这样既能保证 Redis 重启时的速度,又能简单数据丢失的风险。

我们线上是两个都开着。

3.4.nodes.conf

查阅其内容便一目了然:

记录集群内的其他节点信息,用于通信。

例:

3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.187:9720@19720 slave a44ee1eaef7f89cd1013f10638d5d878dd982001 0 1574686485562 4 connected

150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720@19720 myself,master - 0 1574686485000 2 connected 5461-10922

f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.184:9720@19720 master - 0 1574686484000 1 connected 0-5460

a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720@19720 master - 0 1574686486000 3 connected 10923-16383

699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720@19720 slave f8b4cc1d884eb3ced239c572e016a49cabd0313f 0 1574686486563 5 connected

3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720@19720 slave 150da7a79af740c55a61124f1d422fb9fcd19459 0 1574686484560 6 connected

vars currentEpoch 6 lastVoteEpoch 0

第一个字段是节点 ID,一个40个字符的随机字符串,当一个节点被创建时不会再发生变化(除非CLUSTER RESET HARD被使用),所以当pod重启前我们只要nodeId对应的ip:port改掉即可,就可以保证集群的正常使用。

(2).容器重启导致节点ip变化的问题解决

2.1.相关配置方式

在redis-configmap.yaml中有这么一段脚本:

fix-ip.sh: |

#!/bin/sh

CLUSTER_CONFIG="/data/nodes.conf"

if [ -f ${CLUSTER_CONFIG} ]; then

if [ -z "${POD_IP}" ]; then

echo "Unable to determine Pod IP address!"

exit 1

fi

echo "Updating my IP to ${POD_IP} in ${CLUSTER_CONFIG}"

sed -i.bak -e "/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/${POD_IP}/" ${CLUSTER_CONFIG} #改

nodes.conf中本机的ip地址,因为pod每次重启后会导致ip改变。

fi

exec "$@"

这个脚本在容器启动后执行,修改当前redis节点实例的nodes.conf,将本机实例的node编号对应的ip换成新的podIP。由于nodes.conf是由redis-cluster集群维护,所以当这个节点实例启动时,redis-cluster也会将nodes.conf的本地修改同步到当前集群内的其他redis节点的nodes.conf文件,会有一个sync操作。

在redis-statefulset.yaml中的启动命令:

command: ["/conf/fix-ip.sh", "redis-server", "/conf/redis.conf"]

先执行fix-ip.sh修改nodes.conf,然后再启动redis-server,这样才能保证redis-cluster将nodes.conf的更改同步到其他节点实例。

2.2.整个操作过程演示

集群最初IP:

[root@future redis-cluster-min]# kubectl get pod -n redis-cluster-min -o wide

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES

redis-hkc-0 1/1 Running 0 38h 10.244.0.192 future <none> <none>

redis-hkc-1 1/1 Running 0 39h 10.244.0.185 future <none> <none>

redis-hkc-2 1/1 Running 0 39h 10.244.0.186 future <none> <none>

redis-hkc-3 1/1 Running 0 39h 10.244.0.187 future <none> <none>

redis-hkc-4 1/1 Running 0 39h 10.244.0.188 future <none> <none>

redis-hkc-5 1/1 Running 0 39h 10.244.0.189 future <none> <none>

我们接下来选择redis-hkc-3重启,然后观察其nodes.conf文件变化,重启前,我们先进入redis-hkc-3查看一下这个实例的nodes.conf中hkc-3的node标识:

[root@future redis-cluster-min]# kubectl exec -it -n redis-cluster-min redis-hkc-3 -- /bin/bash

root@redis-hkc-3:/data# cat nodes.conf

a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720@19720 master - 0 1574688847000 3 connected 10923-16383

f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.192:9720@19720 master - 1574688835599 1574688833292 1 disconnected 0-5460

699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720@19720 slave f8b4cc1d884eb3ced239c572e016a49cabd0313f 0 1574688844318 5 connected

150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720@19720 master - 0 1574688847000 2 connected 5461-10922

3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720@19720 slave 150da7a79af740c55a61124f1d422fb9fcd19459 0 1574688845000 6 connected

3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.187:9720@19720 myself,slave a44ee1eaef7f89cd1013f10638d5d878dd982001 0 1574688844000 4 connected

vars currentEpoch 6 lastVoteEpoch 0

我们再进入redis-hkc-4,看一下redis-hkc-3节点的Node标识在redis-hkc-4的nodes.conf中的配置:

[root@future redis-cluster-min]# kubectl exec -it -n redis-cluster-min redis-hkc-4 -- /bin/bash

root@redis-hkc-4:/data# cat nodes.conf

3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720@19720 slave 150da7a79af740c55a61124f1d422fb9fcd19459 0 1574688845431 6 connected

150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720@19720 master - 0 1574688846433 2 connected 5461-10922

3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.187:9720@19720 slave a44ee1eaef7f89cd1013f10638d5d878dd982001 0 1574688847000 4 connected

f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.192:9720@19720 master - 1574688835609 1574688834406 1 disconnected 0-5460

699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720@19720 myself,slave f8b4cc1d884eb3ced239c572e016a49cabd0313f 0 1574688847000 5 connected

a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720@19720 master - 0 1574688846000 3 connected 10923-16383

vars currentEpoch 6 lastVoteEpoch 0

OK,现在我们杀掉redis-hkc-3这个pod:

kubectl delete -n redis-cluster-min pod redis-hkc-3

然后查看新POD,发现redis-hkc-3的ip变成10.244.0.194:

[root@future redis-cluster-min]# kubectl get pod -n redis-cluster-min -o wide

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES

redis-hkc-0 1/1 Running 0 40h 10.244.0.192 future <none> <none>

redis-hkc-1 1/1 Running 0 41h 10.244.0.185 future <none> <none>

redis-hkc-2 1/1 Running 0 41h 10.244.0.186 future <none> <none>

redis-hkc-3 1/1 Running 0 12s 10.244.0.194 future <none> <none>

redis-hkc-4 1/1 Running 0 41h 10.244.0.188 future <none> <none>

redis-hkc-5 1/1 Running 0 41h 10.244.0.189 future <none> <none>

查看redis-hkc-3的nodes.conf,可以看到对应的ip被自动修改为新IP:10.244.0.194:

[root@future redis-cluster-min]# kubectl exec -it -n redis-cluster-min redis-hkc-3 -- /bin/bash

root@redis-hkc-3:/data# cat nodes.conf

a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720@19720 master - 0 1574688847000 3 connected 10923-16383

f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.192:9720@19720 master - 1574688835599 1574688833292 1 disconnected 0-5460

699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720@19720 slave f8b4cc1d884eb3ced239c572e016a49cabd0313f 0 1574688844318 5 connected

150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720@19720 master - 0 1574688847000 2 connected 5461-10922

3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720@19720 slave 150da7a79af740c55a61124f1d422fb9fcd19459 0 1574688845000 6 connected

3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.194:9720@19720 myself,slave a44ee1eaef7f89cd1013f10638d5d878dd982001 0 1574688844000 4 connected

vars currentEpoch 6 lastVoteEpoch 0

查看redis-hkc-4的nodes.conf,可以看到redis-hkc-3节点对应的ip被自动修改为新IP:10.244.0.194,说明redis-hkc-3启动时,redis-cluster集群将redis-hkc-3的nodes.conf变更同步到了集群的其他节点:

[root@future redis-cluster-min]# kubectl exec -it -n redis-cluster-min redis-hkc-4 -- /bin/bash

root@redis-hkc-4:/data# cat nodes.conf

3df0d7b40c1a52a1ded516372037121da012331e 10.244.0.189:9720@19720 slave 150da7a79af740c55a61124f1d422fb9fcd19459 0 1574834074462 6 connected

150da7a79af740c55a61124f1d422fb9fcd19459 10.244.0.185:9720@19720 master - 0 1574834075000 2 connected 5461-10922

3f99b19459bd62400f92b9f9ea246f465b035eb2 10.244.0.194:9720@19720 slave a44ee1eaef7f89cd1013f10638d5d878dd982001 1574834069654 1574834068000 4 disconnected

f8b4cc1d884eb3ced239c572e016a49cabd0313f 10.244.0.192:9720@19720 master - 0 1574834077000 1 connected 0-5460

699b9e9e9f69bf65055f1f077c02175f2c91385f 10.244.0.188:9720@19720 myself,slave f8b4cc1d884eb3ced239c572e016a49cabd0313f 0 1574834077000 5 connected

a44ee1eaef7f89cd1013f10638d5d878dd982001 10.244.0.186:9720@19720 master - 0 1574834077469 3 connected 10923-16383

vars currentEpoch 6 lastVoteEpoch 0

2.3.应用如何适配

要求应用程序初始化redis-cluster时,address中不能使用ip,要换成域名。这样即使POD重启IP反生变化,也不会波及到应用程序(其实在重启POD的过程中,对应用会有短时间影响)。

如,在本例配置下:

redis.cluster.address=redis-hkc-0.redis-hkc.redis-cluster-min.svc.cluster.local:9720,redis-hkc-1.redis-hkc.redis-cluster-min.svc.cluster.local:9720,redis-hkc-2.redis-hkc.redis-cluster-min.svc.cluster.local:9720,redis-hkc-3.redis-hkc.redis-cluster-min.svc.cluster.local:9720,redis-hkc-4.redis-hkc.redis-cluster-min.svc.cluster.local:9720,redis-hkc-5.redis-hkc.redis-cluster-min.svc.cluster.local:9720

(3).配置文件说明

4个配置文件:

redis-configmap.yaml

redis-pv-local.yaml

redis-service.yaml

redis-statefulset.yaml

1.redis-configmap.yaml

主要放置fix-ip脚本(POD重启前修改nodes.conf)和redis.conf配置文件。

2.redis-pv-local.yaml

本地存储,生产云环境使用NAS云盘(要做充分性能/压力测试)。

3.redis-service.yaml

headless service。

这里的Headless Services主要是使用它作为标识每个redis-node的域名,这样应用程序直接配置6个域名和端口即可,不需要使用ip,其格式为:

$(podname).(headless server name).namespace.svc.cluster.local

即:

redis-hkc-0.redis-hkc.redis-cluster-min.svc.cluster.local:9720,其始终执行有状态下编号为1的pod,达到与PodIP的无关性。

4.redis-statefulset.yaml

主要配置文件,用于定义有状态容器:redis-cluster。

关键配置:

command: ["/conf/fix-ip.sh", "redis-server", "/conf/redis.conf"]

本文分享自微信公众号 - 千里行走(a_thousands_of_miles),作者:千里行走

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • kubernetes-16:制作oraclejdk镜像

    https://github.com/hepyu/oraclejdk-docker-image

    千里行走
  • kubernetes-15:全链路追踪skywalking容器化

    https://github.com/hepyu/k8s-app-config/tree/master/helm/min-cluster-allinone/sk...

    千里行走
  • kubernetes-10:prometheus-operator容器化

    prometheus-operator是专门为k8s集群量身定做的,用于监控k8s集群,同时自带grafana,alertmanager报警等组件;

    千里行走
  • 05.Redis 命令

    05.Redis 命令 Redis 命令 Redis 命令用于在 redis 服务上执行操作。 要在 redis 服务上执行命令需要一个 redis 客户端。R...

    奋斗蒙
  • 搭建Redis集群

    skylark
  • Redis数据库安装

    REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。

    JiekeXu之路
  • Redis大批量上传数据 使用shell与python脚本

    需求是:有大量的ip地址,作为分布式爬虫的任务分配,需要加入到redis队列中,如果使用数据库提取+for+redis-lpush的方式速度非常慢,大约放80w...

    十四君
  • Redigo--用池管理redis连接

    在golang的项目中,若要频繁的用redis(或者其他类似的NoSQL)来存取数据,最好用redigo自带的池来管理连接。 不然的话,每当要操作redis时,...

    李海彬
  • docker|docker安装redis

    本网站记录了最全的各种JavaDEMO ,保证下载,复制就是可用的,包括基础的, 集合的, spring的, Mybatis的等等各种,助力你从菜鸟到大牛,记得...

    微笑的小小刀
  • Redis全异步(HA)Driver设计稿

    现在Redis的集群功能已经Release。但是并没有一个官方直接提供的高可用性的API可以使用。有的只有解决方案,Sentinel和Cluster。所以有必要...

    owent

扫码关注云+社区

领取腾讯云代金券