Redis集群

一、摘要

看完本文你将掌握如下知识点:

  • redis集群的构建方法【redis-5.0.2】
  • redis早期的版本中使用基于ruby的redis-trib.rb命令进行集群创建,新版本推荐使用 redis-cli --cluster,本文就是通过redis-cli --cluster命令实现集群构建。

二、快速创建集群

redis为我们提供了快速创建集群的工具,安装好redis后,在其/redis-5.0.2/utils/create-cluster/目录下存在一个create-cluster命令,通过该命令可以快速创建一个基于本机端口30001~30006的三主三从的redis集群,可以通过修改端口号及服务数量来改变集群的配置。
1.启动6个redis服务,./create-cluster start
2.创建集群,./create-cluster create
3.关闭集群服务,./create-cluster stop
4.清除数据及日志文件,./create-cluster clean

三、源码分析

通过看源码可以很清楚其创建过程
1.启动6个reids服务,通过参数的方式进行启动,在生产环境中建议通过配置文件启动

1
2
3
4
5
6
7
8
9
10
11
if [ "$1" == "start" ]
then
while [ $((PORT < ENDPORT)) != "0" ]; do
PORT=$((PORT+1))
echo "Starting $PORT"
../../src/redis-server --port $PORT --cluster-enabled yes --cluster-config-file nodes-${PORT}.conf --cluster-node-timeout $TIMEOUT --appendonly yes --appendfilename appendonly-${PORT}.aof --dbfilename dump
-${PORT}.rdb --logfile ${PORT}.log --daemonize yes
done
exit 0
fi

参数说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#端口:
port $PORT
#是否启用集群:
cluster-enabled yes
#集群关联文件路径,创建redis集群时自动创建
cluster-config-file nodes-${PORT}.conf
#集群节点间通信的超时时间,毫秒,建议2000,默认15000
cluster-node-timeout $TIMEOUT
#开启aof
appendonly yes
#aof文件名称,注意这里只能是文件名称,若要修改路径需要设置dir属性 ,如dir /home/hanqf/redis-dir/redis-5.0.2/cluster-conf/files/
appendfilename appendonly-${PORT}.aof
#rdb文件名称,同样只能是文件名称,同上路径共用dir属性
dbfilename dump-${PORT}.rdb
#日志文件路径
logfile ${PORT}.log
#后台运行模式启动
daemonize yes

2.构建集群,这里使用的就是redis-cli --cluster命令,可以看出与redis-trib.rb命令类似

1
2
3
4
5
6
7
8
9
10
if [ "$1" == "create" ]
then
HOSTS=""
while [ $((PORT < ENDPORT)) != "0" ]; do
PORT=$((PORT+1))
HOSTS="$HOSTS 127.0.0.1:$PORT"
done
../../src/redis-cli --cluster create $HOSTS --cluster-replicas $REPLICAS
exit 0
fi

create后根的$HOSTS就是redis服务列表

1
127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006

--cluster-replicas $REPLICAS,这里$REPLICAS值为1,表示为每一个master节点分配一个slave节点

四、实际应用

这里我们使用2台服务器,分别启动3个redis服务,来构建一个三主三从的redis集群。

1.服务器IP

  • 10.211.55.15

  • 10.211.55.16

2.端口设置

分别开启俩台服务器的如下端口,前面是redis服务端口,后面是集群通信端口(默认服务端口+10000)

1
2
3
6379,16379
6380,16380
6381,16381

3.redis-{port}.conf

这里需要按照上面的参数说明进行配置,如我们配置号redis-6379.conf后,可以通过如下命令进行复制

1
2
more redis-6379.conf | sed 's/6379/6380/g' > redis-6380.conf
more redis-6379.conf | sed 's/6379/6381/g' > redis-6381.conf

4.启动服务

1
2
3
4
5
6
7
8
9
10
#10.211.55.15
./redis-server redis-6379.conf
./redis-server redis-6380.conf
./redis-server redis-6381.conf


#10.211.55.16
./redis-server redis-6379.conf
./redis-server redis-6380.conf
./redis-server redis-6381.conf

5.构建集群

1
./redis-cli --cluster create 10.211.55.15:6379 10.211.55.15:6380 10.211.55.15:6381 10.211.55.16:6379 10.211.55.16:6380 10.211.55.16:6381  --cluster-replicas 1

五、集群相关命令

1.健康检查

1
2
# 后面可以是集群中任意节点
./redis-cli --cluster check 10.211.55.15:6380

输出如下,可以看到集群中的主从关系,以及每个master中含有key的数量:

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
10.211.55.15:6380 (c39c1e8a...) -> 2 keys | 5461 slots | 1 slaves.
10.211.55.16:6380 (3edc1dae...) -> 5 keys | 5461 slots | 1 slaves.
10.211.55.16:6379 (4dd31f17...) -> 2 keys | 5462 slots | 1 slaves.
[OK] 9 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 10.211.55.15:6380)
M: c39c1e8aa6e07e337aaab03eab3727f739201cd2 10.211.55.15:6380
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: a83903f50621d7627f3ce59f1210af4938b8acc4 10.211.55.15:6381
slots: (0 slots) slave
replicates 4dd31f17e83ef7aa6c7a36474f7f54d842e0ed64
M: 3edc1daeaf3a848156ad8cc601b1374dd0459d9c 10.211.55.16:6380
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 4dd31f17e83ef7aa6c7a36474f7f54d842e0ed64 10.211.55.16:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: cb6a94201d6f5a4e016b1549afc8c976a1a3dda4 10.211.55.15:6379
slots: (0 slots) slave
replicates 3edc1daeaf3a848156ad8cc601b1374dd0459d9c
S: 3f41a95296cb2681ea599f47aaff9c662b3338ad 10.211.55.16:6381
slots: (0 slots) slave
replicates c39c1e8aa6e07e337aaab03eab3727f739201cd2
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

说明:此时如果关闭其中一个master节点,那么其对应的从节点就会升级为主节点,当重新启动原master节点后,则该节点会自动加入集群,并作为从节点。

2.集群扩容,即为集群添加新的主机和从机

2.1通过如下命令添加新的node

说明:10.211.55.15:6382 是新的服务地址,10.211.55.16:6380 是集群中任意一个的服务地址,添加后的服务类型为master。

1
./redis-cli --cluster add-node 10.211.55.15:6382 10.211.55.16:6380

此时我们通过健康检查可以看到新加入的服务没有分配槽点:

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
./redis-cli --cluster check 10.211.55.15:6380
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 10.211.55.15:6379: Connection refused
10.211.55.15:6380 (a5f63b8e...) -> 2 keys | 5461 slots | 1 slaves.
10.211.55.16:6379 (15506850...) -> 2 keys | 5462 slots | 1 slaves.
10.211.55.15:6382 (316e068f...) -> 0 keys | 0 slots | 0 slaves. #注意,这里新添加的主机没有分配槽(slot),需要先进行分配才能使用
10.211.55.16:6380 (d944c0b1...) -> 5 keys | 5461 slots | 0 slaves.
[OK] 9 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 10.211.55.15:6380)
M: a5f63b8e4f24a73d36da9e0bbf84988d7c5558d3 10.211.55.15:6380
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: 15506850b235f4277306368533cacf4a5ec1bbd1 10.211.55.16:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 316e068fd71ee228299198a271efd839d3493835 10.211.55.15:6382
slots: (0 slots) master
S: b3c0e06da5b5d694c3a68408fb4c8f7607d7e9e0 10.211.55.16:6381
slots: (0 slots) slave
replicates a5f63b8e4f24a73d36da9e0bbf84988d7c5558d3
M: d944c0b19e92af325b882e3a86ff09c2b6b53f47 10.211.55.16:6380
slots:[0-5460] (5461 slots) master
S: 4bce4c24959bda55d087296e86f58ec03186d3ae 10.211.55.15:6381
slots: (0 slots) slave
replicates 15506850b235f4277306368533cacf4a5ec1bbd1
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

2.2分配槽

1
./redis-cli --cluster reshard 10.211.55.15:6382

执行命令后会有如下设置:
1.问你是否从原有的1-16384个槽中分配多少到新的主节点,我们这里分配4000为例,回车
2:然后紧接着会询问你给id为谁的主节点分配,这里就是新加的节点10.211.55.15:6382,其对应的Id为:316e068fd71ee228299198a271efd839d3493835
3:询问你是从所有的空间去给这个节点分配空间还是从某一个节点分配,我这里输入all 回车继续
4:然后会给你分配出一个分配计划,输入yes开始分配。完成ok

此时再次运行健康检查可以看到槽点已经分配成功

1
2
3
4
5
6
7
8
9
./redis-cli --cluster check 10.211.55.15:6380
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
localhost:6380 (a5f63b8e...) -> 1 keys | 4128 slots | 1 slaves.
10.211.55.16:6379 (15506850...) -> 2 keys | 4128 slots | 1 slaves.
10.211.55.15:6382 (316e068f...) -> 2 keys | 4000 slots | 0 slaves.
10.211.55.16:6380 (d944c0b1...) -> 4 keys | 4128 slots | 1 slaves.
[OK] 9 keys in 4 masters.
0.00 keys per slot on average.
………………………………

2.3平衡槽,就是均匀分配集群中的所有槽到所有的节点,该步非必须,只是看着好看点

1
./redis-cli --cluster rebalance --cluster-threshold 1 10.211.55.15:6382
1
2
3
4
5
6
7
8
./redis-cli --cluster info 10.211.55.15:6380
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
localhost:6380 (a5f63b8e...) -> 1 keys | 4096 slots | 1 slaves.
10.211.55.16:6379 (15506850...) -> 2 keys | 4096 slots | 1 slaves.
10.211.55.15:6382 (316e068f...) -> 2 keys | 4096 slots | 0 slaves.
10.211.55.16:6380 (d944c0b1...) -> 4 keys | 4096 slots | 1 slaves.
[OK] 9 keys in 4 masters.
0.00 keys per slot on average.

2.4为新加入的master添加slave

同样需要先加入集群

1
./redis-cli --cluster add-node 10.211.55.16:6382 10.211.55.16:6380

之后不需要做分配和平衡槽的操作
登录这个redis, ./redis-cli -h 10.211.55.16 -p 6382

1
2
127.0.0.1:6382> cluster replicate 316e068fd71ee228299198a271efd839d3493835 #主节点的id
OK

3.删除节点

3.1删除主节点

删除节点前,节点上的槽要被清空

1
./redis-cli --cluster reshard 10.211.55.15:6382 #集群中任意ip即可

1.问你是否从原有的1-16384个槽中分配多少到新的主节点我们这里分配4096,即该节点上的槽数
2:然后紧接着会询问你给id为谁的主节点分配,这里我们分配给10.211.55.16:6379,即15506850b235f4277306368533cacf4a5ec1bbd1
3:询问你是从所有的空间去给这个节点分配空间还是从某一个节点分配
我这里输入要移出的节点ID ,即316e068fd71ee228299198a271efd839d3493835 回车继续 输入 done
4:然后会给你分配出一个分配计划,输入yes开始分配。完成ok

执行删除节点命令

1
2
3
4
5
./redis-cli --cluster del-node 10.211.55.16:6379 316e068fd71ee228299198a271efd839d3493835
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Removing node 316e068fd71ee228299198a271efd839d3493835 from cluster 10.211.55.16:6379
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

说明:
删除节点会自动关闭被移出的redis服务,此时,该主节点的从节点会自动转为其它主节点的从节点,而不会升级为主节点

3.2删除从节点

直接执行节点删除命令

1
./redis-cli --cluster del-node 10.211.55.16:6379 从节点ID