docker pull redis:6.0.8
目录层级遵循
${prefix}/cluster/host/xx
如:
启动
docker run -d --privileged=true \
--name redis-node-01 --net host \
-v /docker/redis/cluster_01/node_01/data:/data \
redis:6.0.8 \
--cluster-enabled yes --appendonly yes --port 6381
docker run -d --privileged=true \
--name redis-node-02 --net host \
-v /docker/redis/cluster_01/node_02/data:/data \
redis:6.0.8 \
--cluster-enabled yes --appendonly yes --port 6382
docker run -d --privileged=true \
--name redis-node-03 --net host \
-v /docker/redis/cluster_01/node_03/data:/data \
redis:6.0.8 \
--cluster-enabled yes --appendonly yes --port 6383
docker run -d --privileged=true \
--name redis-node-04 --net host \
-v /docker/redis/cluster_01/node_04/data:/data \
redis:6.0.8 \
--cluster-enabled yes --appendonly yes --port 6384
docker run -d --privileged=true \
--name redis-node-05 --net host \
-v /docker/redis/cluster_01/node_05/data:/data \
redis:6.0.8 \
--cluster-enabled yes --appendonly yes --port 6385
docker run -d --privileged=true \
--name redis-node-06 --net host \
-v /docker/redis/cluster_01/node_06/data:/data \
redis:6.0.8 \
--cluster-enabled yes --appendonly yes --port 6386
参数说明
-d
redis 作为服务后台运行
–name
redis 节点名字
net host
容器网络模式,使用宿主机 IP 和端口
此模式下不能使用 -p 或 -P 指定端口
否则会出现下面警告,配置也不会生效
Published ports are discarded when using host network mode
–privileged=true
获取宿主机 root 权限
-v
添加数据卷挂载
–cluster-enabled
开启 redis 集群
appendonly yes
开启 redis 持久化
–port
指定 redis 节点的端口
配合 -net host 指定端口
主从配置
任选一个 docker 节点,进入容器,通过下面 reids-cli 配置集群
redis-cli --cluster create 192.168.3.11:6381 192.168.3.11:6382 192.168.3.11:6383 192.168.3.11:6384 192.168.3.11:6385 192.168.3.11:6386 --cluster-replicas 1
参数说明
集群配置效果如下图
hash 槽 相关说明见连接

注意 这里有一步确认,需要输入后看到下图红框才算成功

注意
node is not empty
[ERR] Node 192.168.3.11:6381 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
说明对应节点的存储位置下有数据,需要删除或移动。
按上面示例的配置搭建时,可以使用下面指令清理
rm -rf /docker/redis/cluster_01
redis-cli --cluster create 时,cluster node 列表务必核对清楚,否则容易莫名其妙少一个节点
redis-cli --cluster create 时,中间有一步交互确认,需要键入 yes,否则集群搭建不起来
(error) MOVED
(error) MOVED 15495 192.168.3.11:6383
集群模式下,登录 redis-cli 需要添加 -c 参数,如下所示
redis-cli -c -p 6381
因为 redis 依赖 hash 槽,对 key 进行操作时会先计算 hash 槽,并移动到此 hash 对应的节点上
示例中报错信息里的 15495 即 hash 槽位,192.168.3.11:6383 即对应节点
没有 -c 参数会使移动失败,因此报错
Redis Assistant (看上去很不错,但收费)
Another Redis Desktop Manager
无法连接时,查看防火墙相关配置,参考 firewall-cmd 指令




添加主节点
redis-cli --cluster add-node 新主节点Ip端口 集群中节点Ip端口
添加从节点
redis-cli --cluster add-node 新从节点Ip端口 集群中节点Ip端口 --cluster-slave --cluster-master-id 主节点node-id
redis-cli --cluster reshard 集群中节点Ip端口
redis-cli --cluster rebalance 集群中节点Ip端口
当每个节点的 key 都很少时,使用此命令无效,并提示
*** No rebalancing needed! All nodes are within the 2.00% threshold.
redis-cli --cluster del-node 集群中节点Ip端口
参考上面示例中 redis-cli --cluster ckeck 的输出,此时 redis 集群的结构如下图所示

在上面集群中
运行新 redis nodes
docker run -d --privileged=true \
--name redis-node-07 --net host \
-v /docker/redis/cluster_01/node_07/data:/data \
redis:6.0.8 \
--cluster-enabled yes --appendonly yes --port 6387
docker run -d --privileged=true \
--name redis-node-08 --net host \
-v /docker/redis/cluster_01/node_08/data:/data \
redis:6.0.8 \
--cluster-enabled yes --appendonly yes --port 6388

进入新节点容器,分别以主从身份将新节点加入集群
docker exec -it 129eb34dcf09 /bin/bash
redis-cli --cluster add-node 192.168.3.11:6387 192.168.3.11:6381
exit
docker exec -it 15e47f2a1bb5 /bin/bash
redis-cli --cluster add-node 192.168.3.11:6388 192.168.3.11:6381 --cluster-slave --cluster-master-id 14b47d80f327d499820def9bdf286c498f03f653
exit


==任意容器中查看集群状态 ==
redis-cli --cluster check 192.168.3.11:6381

重新分配 hash 槽
此时无法使用 redis-cli --cluster rebalance 重新分配 hash 槽,因为所有节点的 hash 槽占用率都很低
因此使用 redis-cli --cluster reshard 命令

说明:
使用下面指令查询分配结果
redis-cli --cluster check 192.168.3.11:6381
可以看到现在是 4 个 master 均分所有 hash 槽,
且每个扩容前的节点在自己的 hash 槽区间上从开头(左侧)截取所需数量的 hash 槽进行让渡
新节点(6387) 持有的 hash 槽由 3 个区间段组成

以移除集群中 6387/6388 两个节点为例
重新分配 hash 槽
root@msi-linux7:/data# redis-cli --cluster reshard 192.168.3.11:6381

说明:
可以使用任意集群中的节点进行 hash 槽的重分配
第一步需要确认分配 hash 槽的数量
示例中是重新分配待移除节点上的所有 hash 槽
第二步输入接受 hash 槽的 node 的 id
示例中为了演示方便都用 6381 节点接受
也可以分多次分配
第三步确认 hash 槽来源,
要移除 6387 上的 hash 槽,所以填写 6387 的 node id
然后输入 done 完成
第四步是一个确认,询问是否按分析的结果执行分配,输入 yes 即可
检查重新分配结果
redis-cli --cluster check 192.168.3.11:6381

可见待删除的节点 6387 已经没有 hash 槽了
同时,原本 6387 的 slave 已经过继给了 6381
删除节点
redis-cli --cluster del-node 192.168.3.11:6381 14b47d80f327d499820def9bdf286c498f03f653
redis-cli --cluster del-node 192.168.3.11:6381 886f415bc4d296a7d8794a88f47e7e9f35f7a2a9

如果有需要,可以重新分配 hash 槽,使三个节点负载均衡
或者在一开始分配时,就考虑此问题
重分配 hash 槽和节点删除的顺序问题
有些教程和帖子上的顺序为
因作者实践经验有限,不能验证,但考虑
若先删除从节点,在 hash 槽重分配完成前,主节点 6387 挂了的情况时可能存在问题
因此此贴中的顺序是先重新分配 hash 槽