Redis Cluster 线上动态调整主从关系

起因:我的 Redis Cluster 集群是使用三台服务器部署的,三主三从,但是在运行一段时间后,中间可能出现了超时导致主从节点切换,然后就出现了一台服务器上有两个主节点的情况,必须把它们的关系重新调整一下

+++ 点击折叠
这是被隐藏的内容
+++

提示
这是一个提示

在新版本中,redis-cli 工具已经集成了 redis-trip 了,可以直接使用
接下来会使用到的命令有:check reshard del-node add-node rebalance
下面的所有操作,如果 Redis 有设置密码,那么都需要在指令后边添加 -a <passwd>

看指令名就大概能够猜到,调整的流程是:

  1. 先将服务器上的主节点 B 的哈希槽暂时移动到其他主节点(使用 checkreshard

    1
    2
    3
    4
    5
    6
    7
    8
    # 获取该主节点所拥有的槽数
    redis-cli --cluster check
    ## 这里会输出每个主节点占用多少槽位 => (xxx slots)

    # 将所有槽位暂存到其他主节点
    redis-cli --cluster reshard <要取消主节点身份的 IP:PORT>
    ## 这里需要输入槽的个数,就是上边的 xxx
    ## 然后输入要接受这些槽的主节点 ID,然后输入 done 就可以了
  2. 然后将主节点 1-B 从集群中移除,这一步需要没有数据才能够移除,所以第一步先移除哈希槽(使用 del-node

    1
    redis-cli --cluster del-node <要取消主节点身份的 IP:PORT> <要取消主节点身份的节点 ID>
  3. 接着将另一台服务器的从节点 2-B 从集群中移除,从节点可以直接移除没有限制(使用 del-node

    1
    redis-cli --cluster del-node <要成为新主节点的 IP:PORT> <要成为新主节点的节点 ID>
  4. 再将该从节点 2-B 加入集群,默认就是主节点了(使用 add-node

    1
    redis-cli --cluster add-node <要成为新主节点的 IP:PORT> <集群中任意的 IP:PORT>
  5. 再将主节点 1-B 以从节点的身份加入集群(使用 add-node

    1
    redis-cli --cluster add-node <要取消主节点身份的 IP:PORT> --cluster-slave --cluster-master-id <目标主节点 ID>
  6. 最后将槽从新分配,使得新晋的主节点 2-B 分配到哈希槽(使用 rebalance

    1
    2
    # 注意要加上 --cluster-use-empty-masters 允许槽位位空的主节点参与从新分配,默认是不允许的
    redis-cli --cluster rebalance <集群中任意的 IP:PORT> --cluster-use-empty-masters

至此,线上动态调整主从关系完成~

最后再附一份集群操作的使用说明(直接使用 redis-cli --cluster help 就能看到的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
redis-cli --cluster help
Cluster Manager Commands:
create host1:port1 ... hostN:portN #创建集群
--cluster-replicas <arg> #从节点个数
check host:port #检查集群
--cluster-search-multiple-owners #检查是否有槽同时被分配给了多个节点
info host:port #查看集群状态
fix host:port #修复集群
--cluster-search-multiple-owners #修复槽的重复分配问题
reshard host:port #指定集群的任意一节点进行迁移slot,重新分slots
--cluster-from <arg> #需要从哪些源节点上迁移slot,可从多个源节点完成迁移,以逗号隔开,传递的是节点的node id,还可以直接传递--from all,这样源节点就是集群的所有节点,不传递该参数的话,则会在迁移过程中提示用户输入
--cluster-to <arg> #slot需要迁移的目的节点的node id,目的节点只能填写一个,不传递该参数的话,则会在迁移过程中提示用户输入
--cluster-slots <arg> #需要迁移的slot数量,不传递该参数的话,则会在迁移过程中提示用户输入。
--cluster-yes #指定迁移时的确认输入
--cluster-timeout <arg> #设置migrate命令的超时时间
--cluster-pipeline <arg> #定义cluster getkeysinslot命令一次取出的key数量,不传的话使用默认值为10
--cluster-replace #是否直接replace到目标节点
rebalance host:port #指定集群的任意一节点进行平衡集群节点slot数量
--cluster-weight <node1=w1...nodeN=wN> #指定集群节点的权重
--cluster-use-empty-masters #设置可以让没有分配slot的主节点参与,默认不允许
--cluster-timeout <arg> #设置migrate命令的超时时间
--cluster-simulate #模拟rebalance操作,不会真正执行迁移操作
--cluster-pipeline <arg> #定义cluster getkeysinslot命令一次取出的key数量,默认值为10
--cluster-threshold <arg> #迁移的slot阈值超过threshold,执行rebalance操作
--cluster-replace #是否直接replace到目标节点
add-node new_host:new_port existing_host:existing_port #添加节点,把新节点加入到指定的集群,默认添加主节点
--cluster-slave #新节点作为从节点,默认随机一个主节点
--cluster-master-id <arg> #给新节点指定主节点
del-node host:port node_id #删除给定的一个节点,成功后关闭该节点服务
call host:port command arg arg .. arg #在集群的所有节点执行相关命令
set-timeout host:port milliseconds #设置cluster-node-timeout
import host:port #将外部redis数据导入集群
--cluster-from <arg> #将指定实例的数据导入到集群
--cluster-copy #migrate时指定copy
--cluster-replace #migrate时指定replace
help