docker 安装 redis 集群
集群搭建(三主三从)
集群搭建
集群中的节点都需要打开两个 TCP 连接。一个连接用于正常的给 Client 提供服务,比如 6379,还有一个额外的端口(通过在这个端口号上加10000)作为数据端口,例如:redis的端口为 6379,那么另外一个需要开通的端口是:6379 + 10000, 即需要开启 16379
。
16379 端口用于集群总线,这是一个用二进制协议的点对点通信信道。这个集群总线(Cluster bus)用于节点的失败侦测、配置更新、故障转移授权等等。
-
运行节点
docker run -d --name redis-node1 -p 16381:16381 --privileged=true -v /data/redis/share/node1/data:/data redis:latest --cluster-enabled yes --appendonly yes --port 6381 docker run -d --name redis-node2 -p 16382:16382 --privileged=true -v /data/redis/share/node2/data:/data redis:latest --cluster-enabled yes --appendonly yes --port 6382 docker run -d --name redis-node3 -p 16383:16383 --privileged=true -v /data/redis/share/node3/data:/data redis:latest --cluster-enabled yes --appendonly yes --port 6383 docker run -d --name redis-node4 -p 16384:16384 --privileged=true -v /data/redis/share/node4/data:/data redis:latest --cluster-enabled yes --appendonly yes --port 6384 docker run -d --name redis-node5 -p 16385:16385 --privileged=true -v /data/redis/share/node5/data:/data redis:latest --cluster-enabled yes --appendonly yes --port 6385 docker run -d --name redis-node6 -p 16386:16386 --privileged=true -v /data/redis/share/node6/data:/data redis:latest --cluster-enabled yes --appendonly yes --port 6386
-p 16386:16386:集群总线端口
--port:redis占用端口
注意:一定要开启端口
-
进入 redis 节点,创建集群关系,
redis-cli --cluster create
。[root@VM-4-7-centos ~]# docker exec -it redis-node1 bash root@VM-4-7-centos:/data# redis-cli --cluster create 10.0.4.7:6381 10.0.4.7:6382 10.0.4.7:6383 10.0.4.7:6384 10.0.4.7:6385 10.0.4.7:6386 --cluster-replicas 1
--cluster-replicas:副本数量
-
查看集群状况,
redis-cli --cluster check 10.0.4.7:6381
查看集群信息命令很多,以下是常用命令
需要进入redis内部:
cluster nodes
cluster info
不需要进入 redis 内部:
redis-cli --cluster check redis机器ip:redis端口
-
插入数据测试
(error) MOVED 12706 10.0.4.7:6383
正常单机连接的情况下,插入数据可能会出现以上错误
k1 经过哈希运算得到的槽为12706,而redis-node只维护了0-5460的槽,路由不到 12706 槽位,所以插入失败
解决方法:
使用集群连接状态:
redis-cli -p 6381 -c
-c
:开启集群模式-c:Enable cluster mode (follow -ASK and -MOVED redirections)
- ask:临时重定向,后续操作依然在旧节点。
- moved:永久重定向,后续操作在新节点。
[root@VM-4-7-centos ~]# docker exec -it redis-node1 bash root@VM-4-7-centos:/data# redis-cli -p 6381 -c
扩容
通过 docker 新建两台 redis 机器,一主一从;主机端口:6387,从机端口:6388。
-
创建机器,注意端口开放。
docker run -d --name redis-node7 -p 16387:16387 --privileged=true -v /data/redis/share/node7/data:/data redis:latest --cluster-enabled yes --appendonly yes --port 6387 docker run -d --name redis-node8 -p 16388:16388 --privileged=true -v /data/redis/share/node8/data:/data redis:latest --cluster-enabled yes --appendonly yes --port 6388
-
添加主机,redis-cli --cluster add-node new_host:new_port existing_host:existing_port。这个操作会将要加入的那台机器添加进集群,并设置为 master 机器。
同时添加主从,前面的机器为从机,后面的为主机:
redis-cli --cluster add-node new_slave_host:new_slave_port new_master_host:new_master_port existing_host:existing_port
添加从机指定主机id:
redis-cli --cluster add-node new_slave_host:new_slave_port existing_host:existing_port --cluster-slave --cluster-master-id <id>
redis-cli --cluster add-node 10.0.4.7:6387 10.0.4.7:6381
-
查看集群状况
redis-cli --cluster check 10.0.4.7:6381
-
添加从机
# --cluster-master-id <arg>:arg 所属主机id redis-cli --cluster add-node 10.0.4.7:6388 10.0.4.7:6381 --cluster-slave --cluster-master-id e244827efe2bf120e738567bf5d4cbe7a61e320e
-
查询当前集群状况,
redis-cli --cluster check 10.0.4.7:6381
-
重新分配槽号,
redis-cli --cluster reshard 10.0.4.7:6381
目前只能手动指定槽数分配,会从其余 master 节点中分配一些槽位到新的节点,如果加入新节点,redis 不能对重新平均分配集群的哈希槽。redis 官网参考
This allows to build some automatism if you are likely to reshard often, however currently there is no way for
redis-cli
to automatically rebalance the cluster checking the distribution of keys across the cluster nodes and intelligently moving slots as needed. This feature will be added in the future.如果您可能经常重新分片,这允许构建一些自动化,但是目前 redis-cli 无法自动重新平衡集群,检查集群节点之间的密钥分配并根据需要智能移动插槽。此功能将在未来添加。
-
How many slots do you want to move (from 1 to 16384)?,设置新的节点占用多少个槽位。
-
What is the receiving node ID?,这些槽位分配给那个节点。
-
Please enter all the source node IDs.Type 'all' to use all the nodes as source nodes for the hash slots.
要从哪些节点获取这些槽位,all:所有 master 节点。
-
-
查看集群状况,
redis-cli --cluster check 10.0.4.7:6381
。我这边因为分配了两次,所以 6387 端口的 redis 拥有 8192 个槽位。 -
查看槽位分配的均衡性,
redis-cli --cluster rebalance 10.0.4.7:6381
如果当前集群中槽位分配不均匀,rebalance 命令会触发重新分配,将多余的槽位分配给其余 master 节点。因为我上面分配了两次槽位,6387节点槽位为 8192个。
rebalance之后槽位 = 8192 - 1366 -1365 - 1365 = 4096。(正好和 16384 / 4 相等)
再次执行,节点负责的槽数据差异在2%以内,集群槽位分配是均匀的。
-
再看下集群状况,每个 master 节点都分配了 4096 个槽位。
缩容
流程:先删除从节点 6388 -> 重新分配槽位 -> 删除主节点 6387
-
删除从节点 6388,
redis-cli --cluster del-node 节点ip:端口 节点id
redis-cli --cluster del-node 10.0.4.7:6388 ba4f57a9d38e6b3c52abb4c1008243e2a2fe130e
这里的ip、端口、id都是被删除节点的
看下集群状态,6388节点已经没了
-
分配槽位,可以将 6387 节点的槽位都分给某一台机器,也可以平均分配,这里我都分配给 6381节点。(如果不满意也可以在 6387 节点删除完后通过
rabalance
命令自动分配槽位)不能直接删除 master 节点,一定要先重新分配,附上失败图
redis-cli --cluster reshard 10.0.4.7:6381
看下集群状态
注意此时 6387 节点退化成了 slave节点,并且所属的 master节点为 6381
-
删除 6387 节点
redis-cli --cluster del-node 10.0.4.7:6387 e244827efe2bf120e738567bf5d4cbe7a61e320e
看下集群状态,6381 节点下的从节点又变成了 1 个
-
自动分配槽位,
redis-cli --cluster rebalance 10.0.4.7:6381
,附上集群状态图(3个 master 节点平分 16384 个槽位):