三主三从,三个主机都有一个从机

创建网络

docker network create redis --subnet 172.38.0.0/16

查看创建的网络

[root@swcode ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
0bfe49ec372b bridge bridge local
9f161ce28618 redis bridge local

配置文件

使用shell脚本创建6个配置文件,直接复制到命令行。

for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

启动容器

使用shell脚本启动6个容器

for port in $(seq 1 6); \
do \
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
done

创建集群

进入容器内部

docker exec -it redis-1 /bin/sh

开启集群

我们使用的是Redis7.0.5版本,集群管理已经集成到了redis-cli中,格式如下:

redis-cli --cluster create --cluster-replicas 1 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379

命令说明:

  • redid-cli --cluster或者./redis-trib.rb:代表集群操作命令
  • create:代表是创建集群
  • --replicas 1或者--cluster-replicas 1:指定集群中每个master的副本个数为1,此时节点总数 / (replicas + 1)得到的就是master的数量。因此节点列表中的前n个就是master,其他节点都是slave节点,随机分配到不同master

三个主机,三个从机。输入yes即可

>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

使用cluster nodes查看集群节点信息

127.0.0.1:6379> cluster nodes
f7475f5c7f4c9a72fc9180d1493d9f6e419e5342 172.38.0.16:6379@16379 slave 7542db82e4f938492fb01467ed5aa82afc8887b1 0 1676615856000 6 connected
b1def78e500625b51dbf43fb569ee7519944ebdb 172.38.0.13:6379@16379 master - 0 1676615857572 3 connected 10923-16383
7542db82e4f938492fb01467ed5aa82afc8887b1 172.38.0.12:6379@16379 master - 0 1676615856470 2 connected 5461-10922
21a38e75f20e71dd04854ab7e44251cc618f9ae6 172.38.0.11:6379@16379 myself,master - 0 1676615857000 1 connected 0-5460
97ec6c5ad97335c60d5735f5bb939931ae7ee667 172.38.0.15:6379@16379 slave 21a38e75f20e71dd04854ab7e44251cc618f9ae6 0 1676615857472 5 connected
a602a84a6e5435e7bbdb7fb9d59c4eb3ece2ac0f 172.38.0.14:6379@16379 slave b1def78e500625b51dbf43fb569ee7519944ebdb 0 1676615856000 4 connected

其中11、12、13为master,14、15、16为slave,且<11, 15>、<12, 16>、<13, 14>。

分片集群的搭建过程可查看:

测试

测试GET/SET

在容器内部,使用-c连接Redis集群

redis-cli -c

set一个值

127.0.0.1:6379> set num 123
OK

再set一个值,a计算得到的hash值为15495,该值所在的节点为redis-3,自动切换到了redis-3

127.0.0.1:6379> set a 1
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
172.38.0.13:6379>

get一个值

172.38.0.13:6379> get a
"1"

再get一个值,可以看到已经切换到redis-1了

172.38.0.13:6379> get num
-> Redirected to slot [2765] located at 172.38.0.11:6379
"123"
172.38.0.11:6379>

测试容错

上一步set a 1,存在了主节点redis-3 (13)上,我们关闭掉容器redis-3

docker stop redis-3

再次get,可以看到我们在redis-4上查到了a

172.38.0.11:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"1"
172.38.0.14:6379>

使用cluster nodes查看节点信息。redis-4成为master,redis-3宕机

172.38.0.14:6379> cluster nodes
a602a84a6e5435e7bbdb7fb9d59c4eb3ece2ac0f 172.38.0.14:6379@16379 myself,master - 0 1676616635000 7 connected 10923-16383
b1def78e500625b51dbf43fb569ee7519944ebdb 172.38.0.13:6379@16379 master,fail - 1676616476060 1676616474558 3 connected