reshard是redis cluster另一核心功能,它通过迁移哈希槽来达到负载匀衡和可扩展目的。

redis-trib.rb完成reshard工作,具体步骤如下:

   (1)输入如下命令:

        ./redis-trib.rb reshard 127.0.0.1:7000

127.0.0.1:7000是集群里任一节点。

   (2)接着要求输入需要迁移的哈希槽数目,提示如下:

        How many slots do you want to move (from 1 to 16384)?

        假如输入100

   (3)接着要求输入迁入哈希槽的目的节点ID,提示如下:

        What is the receiving node ID?

        假如输入ID:1

   (4)接着要求输入迁出哈希槽的源节点ID,提示如下:

       Please enter all the source node IDs.

         Type 'all' to use all the nodes as source nodes for the hash slots.

         Type 'done' once you entered all the source nodes IDs.

       这里可以输入多个节点ID或选择所有节点(all),这里注意源节点ID不能是目的节点ID。

redis-trib.rb会根据上面信息制定迁移计划,并输出如下:

       Resharding plan:

          Moving slot $slot1 from $sourceid1

Moving slot $slot2 from $sourceid2   

       Do you want to proceed with the proposed reshard plan (yes/no)?

       这里输入yes

   (6)接着等待数据迁移完成,至此reshard工作结束。


二、实现原理

./redis-trib.rb reshard命令,上述(1)~(5)步骤都是在redis-trib.rb脚本完成,到第(6)步才真正发命令给redis cluster,前五步比较简单理解,这里就不分析了,下面主要分析第(6)步骤的实现。

    第六步使用了个五集群命令:cluster setslot imporing、cluster setslot migrating、cluster getkeysinslot、migrate和setslot node,下面对这四个命令进行分析:

(1)cluster setslot $slot imporing $sourceid

$sourceid,该节点在收到对该$slot的请求时会进行处理。

(2)cluster setslot $slot migrating $targetid

$targetid,二是正因为该slot的新key写入$targetid,读新key时也需要重定向到$targetid才能获取新key数据。

(3)cluster getkeysinslot $slot $count

该命令是发给source节点的,目的是获取该$slot的$count个keys。

(4)migrate $host $port $key $destination-db $timeout

target节点。

(5)setslot $slot node $targetid

epochconfig值的哈希配置。


总结: 

   通过上面五个操作,就可以完美的迁移slot,迁移过程中不用停止redis cluster对外服务,只要用户能处理重定向情况,就可以完全感知不到迁移slot。