reshard命令可以在线把集群的一些slot从集群原来slot负责节点迁移到新的节点,利用reshard可以完成集群的在线横向扩容和缩容

reshard的参数很多,下面来一一解释一番:

redis-trib.rb reshard host:port –from <arg> –to <arg> –slots <arg> –yes –timeout <arg> –pipeline <arg>

如:redis-trib.rb reshard –from a8b3d0f9b12d63dab3b7337d602245d96dd55844 –to f413fb7e6460308b17cdb71442798e1341b56cbc  –slots 10923 –yes –pipeline 20  127.0.0.1:6383

host:port:这个是必传参数,用来从一个节点获取整个集群信息,相当于获取集群信息的入口。

–from <arg>:需要从哪些源节点上迁移slot,可从多个源节点完成迁移,以逗号隔开,传递的是节点的node id,还可以直接传递–from all,这样源节点就是集群的所有节点,不传递该参数的话,则会在迁移过程中提示用户输入。

–to <arg>:slot需要迁移的目的节点的node id,目的节点只能填写一个,不传递该参数的话,则会在迁移过程中提示用户输入。

–slots <arg>:需要迁移的slot数量,不传递该参数的话,则会在迁移过程中提示用户输入。

–yes:设置该参数,可以在打印执行reshard计划的时候,提示用户输入yes确认后再执行reshard。

–timeout <arg>:设置migrate命令的超时时间。

–pipeline <arg>:定义cluster getkeysinslot命令一次取出的key数量,不传的话使用默认值为10。

迁移的流程如下:

1、通过load_cluster_info_from_node方法装载集群信息。

2、执行check_cluster方法检查集群是否健康。只有健康的集群才能进行迁移。

3、获取需要迁移的slot数量,用户没传递–slots参数,则提示用户手动输入。

4、获取迁移的目的节点,用户没传递–to参数,则提示用户手动输入。此处会检查目的节点必须为master节点。

5、获取迁移的源节点,用户没传递–from参数,则提示用户手动输入。此处会检查源节点必须为master节点。–from all的话,源节点就是除了目的节点外的全部master节点。这里为了保证集群slot分配的平均,建议传递–from all。

6、执行compute_reshard_table方法,计算需要迁移的slot数量如何分配到源节点列表,采用的算法是按照节点负责slot数量由多到少排序,计算每个节点需要迁移的slot的方法为:迁移slot数量 * (该源节点负责的slot数量 / 源节点列表负责的slot总数)。这样算出的数量可能不为整数,这里代码用了下面的方式处理:

n = (numslots/source_tot_slots*s.slots.length)

if i == 0

    n = n.ceil

else

    n = n.floor

这样的处理方式会带来最终分配的slot与请求迁移的slot数量不一致,这个BUG已经在github上提给作者,https://github.com/antirez/redis/issues/2990。

7、打印出reshard计划,如果用户没传–yes,就提示用户确认计划。

8、根据reshard计划,一个个slot的迁移到新节点上,迁移使用move_slot方法,该方法被很多命令使用,具体可以参见下面的迁移流程。move_slot方法传递dots为true和pipeline数量。

9、至此,就完成了全部的迁移任务。

示例:

[root@iZ23gfcvt5xZ redis-3.0.6]# ./src/redis-trib.rb add-node 114.55.116.177:8013 114.55.116.177:8001 (新增集群8013master节点)

7.png

[root@iZ23gfcvt5xZ redis-3.0.6]# ./src/redis-trib.rb reshard 114.55.116.177:8013(为8013master节点重新分配slot)

10.png

[root@iZ23gfcvt5xZ redis-3.0.6]# ./src/redis-trib.rb check 114.55.116.177:8004 (重新check检查集群,8001节点减少1500个slots,8013节点增加1500个slot)

11.png