1. 节点规划:
2 种方式:1 主 + 多从,多对主从,第二种分担主节点、容易扩容缩减。
容器名称 容器 IP 地址 映射端口号 服务运行模式
Redis-master1 172.1.50.11 6391->6379,16391->6379 master
Redis-master2 172.1.50.12 6392->6379,16392->6379 master
Redis-master3 172.1.50.13 6393->6379,16393->6379 master
redis-slave1 172.1.30.11 6394->6379,16394->6379 Slave
redis-slave2 172.1.30.12 6395->6379,16395->6379 Slave
redis-slave3 172.1.30.13 6396->6379,16396->6379 Slave
添加 10000+ 的“bus-port”端口,可以查看官方 redis.conf 的说明:
# * cluster-announce-ip
# * cluster-announce-port
# * cluster-announce-bus-port
# 解释在上述段落下方,多余端口用于集群的自动检测。
官方参考文档。
a. 创建自定义网络
这里为了方便,把 redis 加入之前的 mybridge 网络,方便 php、lua 的调用。高可用时通过主机网络访问,所以主从都要对主机开放端口。如上。
2. 初步创建集群
a. 制作容器创建脚本
简化名称:
clmx 主服务器
clsx 从服务器
docker stop clm1 clm2 clm3 cls1 cls2 cls3
docker rm clm1 clm2 clm3 cls1 cls2 cls3
docker run --name clm1 \
-p 6391:6379 -p 16391:16379 \
--restart=always \
--network=mybridge --ip=172.1.50.11 \
-v /root/tmp/dk/cluster_redis/6391/data:/data \
-v /root/tmp/dk/cluster_redis/6391:/etc/redis \
-d cffycls/redis5:1.7
docker run --name clm2 \
-p 6392:6379 -p 16392:16379 \
--restart=always \
--network=mybridge --ip=172.1.50.12 \
-v /root/tmp/dk/cluster_redis/6392/data:/data \
-v /root/tmp/dk/cluster_redis/6392:/etc/redis \
-d cffycls/redis5:1.7
docker run --name clm3 \
-p 6393:6379 -p 16393:16379 \
--restart=always \
--network=mybridge --ip=172.1.50.13 \
-v /root/tmp/dk/cluster_redis/6393/data:/data \
-v /root/tmp/dk/cluster_redis/6393:/etc/redis \
-d cffycls/redis5:1.7
docker run --name cls1 \
-p 6394:6379 -p 16394:16379 \
--restart=always \
--network=mybridge --ip=172.1.30.11 \
-v /root/tmp/dk/cluster_redis/6394/data:/data \
-v /root/tmp/dk/cluster_redis/6394:/etc/redis \
-d cffycls/redis5:1.7
docker run --name cls2 \
-p 6395:6379 -p 16395:16379 \
--restart=always \
--network=mybridge --ip=172.1.30.12 \
-v /root/tmp/dk/cluster_redis/6395/data:/data \
-v /root/tmp/dk/cluster_redis/6395:/etc/redis \
-d cffycls/redis5:1.7
docker run --name cls3 \
-p 6396:6379 -p 16396:16379 \
--restart=always \
--network=mybridge --ip=172.1.30.13 \
-v /root/tmp/dk/cluster_redis/6396/data:/data \
-v /root/tmp/dk/cluster_redis/6396:/etc/redis \
-d cffycls/redis5:1.7
b. 测试配置文件,建立集群
在之前主从配置基础上,搜索修改
cluster-enabled yes
重启所有容器。
— 节点发现然,后需要在容器命令行设置:
# 进入 172.1.50.1.11
docker exec -it clm1 bash
/ # redis-cli
127.0.0.1:6379> auth 123456
127.0.0.1:6379> info cluster
127.0.0.1:6379> cluster meet 172.1.50.12 6379
127.0.0.1:6379> cluster meet 172.1.50.13 6379
127.0.0.1:6379> cluster meet 172.1.30.11 6379
127.0.0.1:6379> cluster meet 172.1.30.12 6379
127.0.0.1:6379> cluster meet 172.1.30.13 6379
127.0.0.1:6379> cluster nodes
e6f4def93bb888c144c4db308b5a7846d95d257b 172.1.50.11:6379@16379 myself,master - 0 1562061736000 2 connected
a0a5d4e10d97ba63fbf4f6eba3f4cf1f73d53423 172.1.30.12:6379@16379 master - 0 1562061738000 4 connected
c9f17946ca2c22a6dd0269614293e1bf38ae869b 172.1.50.12:6379@16379 master - 0 1562061737000 1 connected
2c5395040cfb9611b515d0424f30c91eba1ec6e8 172.1.30.11:6379@16379 master - 0 1562061740000 3 connected
eff5996aa6d5d9ab048a778246fcc1663322fe7d 172.1.50.13:6379@16379 master - 0 1562061739802 0 connected
67cf166b61e7d892affa6d754a563b5993a9c5a3 172.1.30.13:6379@16379 master - 0 1562061740802 5 connected
这里集群发现一气呵成,感觉很快。不行的话:
看下相应服务器是否能 ping 通;配置文件修改是否到位,这里 6 个节点的配置文件是一致的。
[节点建立握手之后集群还不能正常工作,这时集群处于下线状态,所有的数据读写都被禁止。]
c. 设置从节点
使用 cluster replicate {nodeId} 命令让一个节点成为从节点。其中命令执行必须在对应的从节点上执行,将当前节点设置为 node_id 指定的节点的从节点。
# cls1 容器操作
127.0.0.1:6379> cluster nodes
a0a5d4e10d97ba63fbf4f6eba3f4cf1f73d53423 172.1.30.12:6379@16379 master - 0 1562063939000 4 connected
eff5996aa6d5d9ab048a778246fcc1663322fe7d 172.1.50.13:6379@16379 master - 0 1562063942507 0 connected
c9f17946ca2c22a6dd0269614293e1bf38ae869b 172.1.50.12:6379@16379 master - 0 1562063938000 1 connected
67cf166b61e7d892affa6d754a563b5993a9c5a3 172.1.30.13:6379@16379 master - 0 1562063941505 5 connected
2c5395040cfb9611b515d0424f30c91eba1ec6e8 172.1.30.11:6379@16379 myself,master - 0 1562063940000 3 connected
e6f4def93bb888c144c4db308b5a7846d95d257b 172.1.50.11:6379@16379 master - 0 1562063940503 2 connected
127.0.0.1:6379> cluster REPLICATE e6f4def93bb888c144c4db308b5a7846d95d257b
OK
127.0.0.1:6379> cluster nodes
a0a5d4e10d97ba63fbf4f6eba3f4cf1f73d53423 172.1.30.12:6379@16379 master - 0 1562063991000 4 connected
eff5996aa6d5d9ab048a778246fcc1663322fe7d 172.1.50.13:6379@16379 master - 0 1562063993000 0 connected
c9f17946ca2c22a6dd0269614293e1bf38ae869b 172.1.50.12:6379@16379 master - 0 1562063994634 1 connected
67cf166b61e7d892affa6d754a563b5993a9c5a3 172.1.30.13:6379@16379 master - 0 1562063992000 5 connected
2c5395040cfb9611b515d0424f30c91eba1ec6e8 172.1.30.11:6379@16379 myself,slave e6f4def93bb888c144c4db308b5a7846d95d257b 0 1562063993000 3 connected
e6f4def93bb888c144c4db308b5a7846d95d257b 172.1.50.11:6379@16379 master - 0 1562063993632 2 connected
127.0.0.1:6379>
#同理,在 cls3 上最终结果
/ # redis-cli -h 172.1.30.13
172.1.30.13:6379> cluster nodes
c9f17946ca2c22a6dd0269614293e1bf38ae869b 172.1.50.12:6379@16379 master - 0 1562064342897 1 connected
a0a5d4e10d97ba63fbf4f6eba3f4cf1f73d53423 172.1.30.12:6379@16379 slave c9f17946ca2c22a6dd0269614293e1bf38ae869b 0 1562064345000 4 connected
67cf166b61e7d892affa6d754a563b5993a9c5a3 172.1.30.13:6379@16379 myself,slave eff5996aa6d5d9ab048a778246fcc1663322fe7d 0 1562064343000 5 connected
e6f4def93bb888c144c4db308b5a7846d95d257b 172.1.50.11:6379@16379 master - 0 1562064344000 2 connected
eff5996aa6d5d9ab048a778246fcc1663322fe7d 172.1.50.13:6379@16379 master - 0 1562064345000 0 connected
2c5395040cfb9611b515d0424f30c91eba1ec6e8 172.1.30.11:6379@16379 slave e6f4def93bb888c144c4db308b5a7846d95d257b 0 1562064345904 3 connected
d. 分配槽
[Redis 集群把所有的数据映射到 16384 个槽中。每个 key 会映射为一个固定的槽,只有当节点分配了槽,才能响应和这些槽关联的键命令。]
手动是需要批量分配的,Invalid or out of range slot,百度:
redis-cli -h 服务器 IP -p 端口号 cluster addslots {0..5460} 许多这种没用的,后来找到一位大神的 redis ADDSLOTS 支持区间输入实现,把 ifelse{} 里面的全部替换、加上函数,重新打包编译镜像 OK 了。效果:
172.1.50.13:6379> cluster slots
1) 1) (integer) 0
2) (integer) 5461
3) 1) "172.1.50.11"
2) (integer) 6379
3) "e6f4def93bb888c144c4db308b5a7846d95d257b"
4) 1) "172.1.30.11"
2) (integer) 6379
3) "2c5395040cfb9611b515d0424f30c91eba1ec6e8"
2) 1) (integer) 5462
2) (integer) 10922
3) 1) "172.1.50.12"
2) (integer) 6379
3) "c9f17946ca2c22a6dd0269614293e1bf38ae869b"
4) 1) "172.1.30.12"
2) (integer) 6379
3) "a0a5d4e10d97ba63fbf4f6eba3f4cf1f73d53423"
3) 1) (integer) 10923
2) (integer) 16383
3) 1) "172.1.50.13"
2) (integer) 6379
3) "eff5996aa6d5d9ab048a778246fcc1663322fe7d"
4) 1) "172.1.30.13"
2) (integer) 6379
3) "67cf166b61e7d892affa6d754a563b5993a9c5a3"
172.1.50.13:6379> 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
... ...
其他操作可以看命令帮助或官网。
e. 测试增加节点,删除节点
容器名称 容器 IP 地址 映射端口号 服务运行模式
redis-master4 172.1.50.21 6381->6379,16381->6379 master
redis-slave4 172.1.30.21 6382->6379,16382->6379 slave
docker stop clm4 cls4
docker rm clm4 cls4
docker run --name clm4 \
-p 6381:6379 -p 16381:16379 \
--restart=always \
--network=mybridge --ip=172.1.50.21 \
-v /root/tmp/dk/cluster_redis/6381/data:/data \
-v /root/tmp/dk/cluster_redis/6381:/etc/redis \
-d cffycls/redis5:cluster2
docker run --name cls4 \
-p 6382:6379 -p 16382:16379 \
--restart=always \
--network=mybridge --ip=172.1.30.21 \
-v /root/tmp/dk/cluster_redis/6382/data:/data \
-v /root/tmp/dk/cluster_redis/6382:/etc/redis \
-d cffycls/redis5:cluster2
同理,meet、replicate 后查看 cluster info:cluster_state:ok。但 cluster slots 依然是上面的,槽分配并没有变化,需要继续操作
[
CLUSTER setslot <slot> node <node_id> 将槽指派给指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽,然后再进行指派。
CLUSTER setslot <slot> migrating <node_id> 将本节点的槽迁移到指定的节点中。
CLUSTER setslot <slot> importing <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。
]