文章目录
- 连接集群
- 写入数据
- 单个key写入
- 批量key操作
- 集群查询
- 查询 key 的 slot
- 查询 slot 中 key 的数量
- 查询 slot 中的 key
- 故障转移
- Master宕机
- Master 和 Slave 都宕机
- 集群扩容
- 1.启动两个节点
- 2.添加 master
- 3.分配slot
- 4.添加 slave
- 集群缩容
- 1.删除 slave 节点
- 2.移出 master 的 slot
- 3.删除 master 节点
连接集群
redis-cli -c -p 6380
-c参数表示cluster模式的意思,使用-c参数时,redis-cli会自动检测Redis集群的配置信息,并将命令路由到正确的节点上执行。
写入数据
单个key写入
可以看到当写入name的时候redis会去计算name的hash值,hash值为5798,对应节点的端口号为6381,于是自动重定向到6381的节点上存储数据。当写入languages这个key的时候,由于languages的hash值还在6381这个节点上,因此没有发生重定向。
批量key操作
当使用mset存储多个key时很可能会发生错误。这是因为每个key的hash值不一样,导致可能每个key存储在不同的机器上,所以不能一次性同时写入多个key。要解决这个问题可以使用组
的方式来一次性存储多个key。只要为这些 key 指定一个统一的 group,让这个 group 作为计算 slot 的唯一值。
集群查询
查询 key 的 slot
通过 cluster keyslot 可以查询指定 key 的 slot。例如,下面是查询 msg 和 name 的 slot。
查询 slot 中 key 的数量
通过 cluster countkeysinslot 命令可以查看到指定 slot 所包含的 key 的个数。
查询 slot 中的 key
通过 cluster getkeysinslot 命令可以查看到指定 slot 所包含的 key。
故障转移
分布式系统中的某个 master 如果出现宕机,那么其相应的 slave 就会自动晋升为 master。如果原 master 又重新启动了,那么原 master 会自动变为新 master 的 slave。
Master宕机
通过 cluster nodes 命令可以查看系统的整体架构及连接情况。
可以看到6380、6381、8382均为Master主机,其中6380的Slave是6383;6381的Slave是6384;6382的Slave是6385。现在将6381关机,再登录6384的机器。
可以看到,由于Master6381宕机,它的Slave6384晋升为Master节点。当6381重新启动后,6381会成为6384的Slave。
Master 和 Slave 都宕机
如果某 slot 范围对应节点的 master 与 slave 全部宕机,那么整个分布式系统是否还可以对外提供读服务,就取决于属性 cluster-require-full-coverage 的设置。
该属性有两种取值:
-
yes:默认值。要求所有 slot 节点必须全覆盖的情况下系统才能运行。
-
no:slot 节点不全的情况下系统也可以提供查询服务。
6381和6384现在都关机了。
整个分布式系统已经不能提供服务。
集群扩容
1.启动两个节点
需要添加两个新的节点:端口号为 6386 的节点为 master节点,其下会有一个端口号为 6387 的 slave 节点。写好相应配置文件以后就能启动。
查询集群的连接情况:
2.添加 master
虽然启动了6386和6387这两个节点,但是在没有添加到分布式系统之前,它们两个是孤立节点,每个节点与其它任何节点都没有关系。现在需要为6386这个master分配slot。通过以下命令:
# 格式:
redis-cli --cluster add-node {newHost}:{newPort} {existHost}:{existPort}
redis-cli --cluster add-node 192.168.11.10:6386 192.168.11.10:6385
可以将新的节点添加到系统中。其中{newHost}:{newPort}是新添加节点的地址,{existHost}:{existPort}是原系统中的任意节点地址。添加成功后,通过 redis-cli -c -p 6386 cluster nodes 命令可以看到其它 master 节点都分配有 slot,只有新添加的 master 还没有相应的 slot。当然,通过该命令也可以看到该新节点的动态 ID。
3.分配slot
为新的 master 分配的 slot 来自于其它节点,总 slot 数量并不会改变。所以 slot 分配过程本质是一个 slot 的移动过程。
通过命令:
# 格式:
redis-cli --cluster reshard {existIP}:{existPort}
redis-cli --cluster reshard 192.168.11.10:6384
开启 slot 分配流程,其中地址{existIP}:{existPort}为分布式系统中的任意节点地址。执行完命令后还要输入需要分配slot的数量和分配给谁的id。
现在要选择要移动 slot 的源节点。有两种方案。如果选择键入 all,则所有已存在 slot 的节点都将作为 slot 源节点,即该方案将进行一次 slot 全局大分配。也可以选择其它部分节点作为 slot 源节点。此时将源节点的动态 ID 复制到这里,每个 ID 键入完毕后回车,然后再复制下一个 slot 源节点动态 ID,直至最后一个键入完毕回车后再键入 done。这里我将6380和6382这两个机器作为slot的源节点,从这两个节点中抽取出2500个slot给6386机器。
其首先会检测指定的 slot 源节点的数据,然后制定出 reshard 的方案。
这里会再进行一次 Q&A 交互,询问是否想继续处理推荐的方案。键入 yes,然后开始真正的全局分配,直至完成。现在查看集群的slot分配情况。
可以看到6386的slot确实分配了,只不过并不是连续的,从 [0~1249] 和 [10923~12172]。总共的slot数量:(1249 - 0 + 1) + (12172 - 10923+ 1) = 1250+1250 = 2500。
4.添加 slave
现要将 6387 节点添加为 6386 节点的 slave。当然,首先要确保 6387 节点的 Redis 是启动状态。通过命令:
# 格式
redis-cli --cluster add-node {newHost}:{newPort} {existHost}:{existPort} --cluster-slave --cluster-master-id masterID
redis-cli --cluster add-node 192.168.11.10:6387 192.168.11.10:6380 --cluster-slave --cluster-master-id c939dab0c09bb2d28ece43ea3281b31f0ae27fef
可将新添加的节点直接添加为指定 master 的 slave。最后集群连接的结果如下:
集群缩容
下面要将 slave 节点 6387 与 master 节点 6386 从分布式系统中删除。
1.删除 slave 节点
对于 slave 节点,可以直接通过以下命令删除。
# 格式
redis-cli --cluster del-node <delHost>:<delPort> delNodeID
redis-cli --cluster del-node 192.168.11.10:6387 0bd67fc99e234126658b1316ccddd7a39f51b6df
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KHFxw6oY-1686627266251)(https://liubing-1314895948.cos.ap-chengdu.myqcloud.com/img/202306131114294.png)]
2.移出 master 的 slot
在删除一个 master 之前,必须要保证该 master 上没有分配有 slot。否则无法删除。所以,在删除一个 master 之前,需要先将其上分配的 slot 移出。
# 这个IP和端口号必须是分布式系统中存在的IP和端口号
redis-cli --cluster reshard 192.168.11.10:6384
接下来就是选择移出的slot数量和接收slot的机器ID
What is the receiving node ID?是6380这个master的机器ID;ID(c939dab0c09bb2d28ece43ea3281b31f0ae27fef)为6386的机器ID。后面再输入yes确认就可以了。整个过程和前面的分配slot非常相似。再使用redis-cli -c -p 6386 cluster nodes命令查看发现,6386 节点中已经没有 slot 了。
3.删除 master 节点
# 格式
redis-cli --cluster del-node <delHost>:<delPort> delNodeID
redis-cli --cluster del-node 192.168.11.10:6386 c939dab0c09bb2d28ece43ea3281b31f0ae27fef
此时再查看集群,发现已经没有了 6386 节点。