redis cluster管理工具redis-trib.rb详解

redis-trib.rb是redis的官方推出的管理redis集群的工具,集成在redis的源码src目录下,是基于redis提供的集群命令封装成简单,便捷,实用的操作工具.redis-trib.rb是redis作者用ruby完成的。为了看懂redis-trib.rb,我特意花了一个星期学习了ruby,也被ruby的简洁,明了所吸引.ruby是门非常灵活的语言,redis-trib.rb只用本文对redis-trib.rb的介绍是基于redis 3.0.6版本的源码。阅读本文需要对redis集群功能有一定的了解。关于redis集群功能的介绍,可以参考本人的另一篇文章“redis3.0 cluster function介绍” 

英文root是什么意思suv是什么意思suv是什么意思cpi是什么意思app是什么意思hr是什么意思logo是什么意思生日快乐英文谢谢的英文

$ ruby​​ redis-trib.rb help

用法:redis-trib  

  create host1:port1 ... hostN:portN 
                  --replicas  
  检查主机:port 
  info host:port 
  fix host:port 
                  --timeout  
  reshard主机:端口
                  --from  
                  --to  
                  --slots  
                  --yes 
                  --timeout  
                  --pipeline  
  平衡主机:端口
                  --weight  
                  -自动重
                  --threshold  
                  --use-空大师
                  --timeout  
                  --simulate 
                  --pipeline  
  添加节点new_host:new_port existing_host:existing_port 
                  --slave 
                  --master-ID  
  删除节点的主机:端口NODE_ID 
  设置超时主持人:端口毫秒
  调用主机:端口命令ARG ARG ARG .. 
  进口主机:端口
                  --from  
                  --copy 
                  --replace 
  帮助(显示此帮助)

以支票, fix,reshard,del-node,set-timeout你可以指定集群中任何工作节点的主机和端口。

可以看到redis-trib.rb具有以下功能:
1,创建:创建集群
2,检查:检查集群
3,信息:查看集群信息
4,修复:修复集群
5,reshard:在线迁移时隙
6,重新平衡集群节点时隙数量
7,add-node:将新节点加入集群
8,del node:从集群中删除节点
9,set-timeout:设置集群节点间心跳连接的超时时间
10,call:在集群全部节点上执行命令
11,import:将外部redis数据导入集群
下面从redis-trib.rb使用和源码的角度详介绍redis-trib.rb的每个功能

redis-trib.rb主要有两个类:ClusterNode和RedisTrib.ClusterNode保存了每个节点的信息,RedisTrib则是redis-trib.rb各个功能的实现

ClusterNode对象

先分析ClusterNode源码.ClusterNode有下面几个成员变量(ruby的类成员变量是以@开头的):@r 

:执行redis命令的客户端对象。
@info:保存了该节点的详细信息,包括集群节点命令中自己这行的信息和集群信息的信息。
@dirty:节点信息是否需要更新,如果为true,我们需要把内存的节点更新信息到节点上。@ 
friends:保存了集群其他节点的信息信息。其信息为通过集群节点命令获得的其他节点信息
。ClusterNode有下面一些成员方法:

initialize:ClusterNode的构造方法,需要传入节点的地址信息。friends 
:返回@friends对象。slots 
:返回该节点负责的slots信息
。has_flag?:判断节点信息的标志位是否有给定的标志
。to_s:类似java的toString方法,返回节点的地址信息 。connect:
连接redis节点
。assert_cluster:判断节点开启集群配置
。assert_empty :确定节点目前没有跟任何其他节点握手,同时自己的db数据为空
。load_info:通过集群信息和集群节点导入节点信息
。add_slots:给节点增加slot,该操作只是在内存中修改,并把脏设置成真,等待flush_node_config将内存中的数据同步在节点执行中
。set_as_replica:slave设置复制的主地址.dirty设置成真
。flush_node_config:将内存的数据修改同步在集群节点中执行
info_string:简单的信息信息。
get_config_signature:用户验证集群节点见的集群节点信息是否一致。该方法返回节点的
签名信息info:返回@info对象,包含详细的信息信息
。is_dirty?:判断@dirty。r 
:返回执行redis命令的客户端对象。
有了ClusterNode对象,在处理集群操作的时候,就获得了集群的信息,可以进行集群相关操作。在此先简单介绍下redis-trib.rb脚本的使用,以create为例:

create host1:port1 ... hostN:portN 
       --replicas  
host1:port1 ... hostN:portN表示子参数,这个必须在可选参数之后, - replicas 是可选参数,带的表示后面必须填写一个参数,像--slave这样,后面就不带参数,掌握了这些基本规则,掌握了这些基本规则,就能从帮助命令中获得redis-trib.rb的使用方法。

其他命令大都需要传递host:port,这是redis-trib.rb为了连接集群,需要选择集群中的一个节点,然后通过该节点获得整个集群的信息



创建集群


最简单的命令使用如下:

$ ruby​​ redis-trib.rb create 10.180.157.199:6379 10.180.157.200:6379 10.180.157.201:6379 
有一个slave的创建命令如下:

$ ruby​​ redis-trib.rb create --replicas 1 10.180.157.199:6379 10.180.157.200:6379 10.180.157.201:6379 10.180.157.202:6379 10.180.157.205:6379 10.180.157.208:6379  
创建流程如下:

1,首先为每个节点创建ClusterNode对象,包括连接每个节点。检查每个节点是否为独立且db为空的节点。执行load_info方法导入节点信息
。2,检查传入的主节点数量是否大于等于3个。只有大于3个节点才能组成集群
。3,计算每个主要需要分配的槽数量,以及给主分配奴隶。分配的算法大致如下:
先把节点按照主分类,这样保证master节点能分配到更多的主机中。
不停遍历历史主列表,从每个主机列表中弹出一个节点,放入交织数组。直到所有的节点都弹出为止。
主节点列表就是交错前面的主数字的节点列表。保存在masters数组,
计算每个主节点负责的时隙数量,保存在slots_per_node对象,用于时隙总数除以主数量取整即可。
每个主分配slot_per_node个时隙,最后一个主时隙,分配到16384个时隙接下来
为主分配奴隶,分配算法会尽量保证主和从节点不在同一台主机上。对于分配完指定从数据的节点,还有多余的节点,也将为这些节点寻找master。分配算法会遍历两次大师数组。
第一次遍历大师数组,在余下的节点列表找到replicas数量个slave。每个slave为第一个和master节点主机不一样的节点,则直接取出余下列表的第一个节点。
第二次遍历是在对于节点数除了replicas不为整数,则多余一部分节点。遍历的方式跟第一次一样,只是第一次会一次性给master分配replicas数量个奴隶,而第二次遍历只分配一个,直到余下的节点被全部分配出去。
4,打印出分配信息,并提示用户输入“是”确认是否按照打印出来的分配方式创建集群。
5,输入“yes”后,会执行flush_nodes_config操作,该操作执行前面的分配结果,给主分配槽,让从复制主机,对于还没有握手(cluster meet)的节点,从复制操作无法完成,不过没关系,flush_nodes_config操作出现异常会很快返回,后续握手后会再次执行flush_nodes_config。6 
,给每个节点分配epoch,遍历节点,每个节点分配的epoch比之前节点大1. 
7,节点间开始相互握手,握手的方式为节点列表的其他节点跟第一个节点握手
。8,然后每隔1秒检查一次各个节点是否已经消息同步完成,使用ClusterNode的get_config_signature方法,检查的算法为获得每个节点群集节点信息,个节点,组装成node_id1:slots | node_id2:slot2 | ...的字符串。如果每个节点获得字符串都相同,即认为握手成功
。9,此后会再执行一次flush_nodes_config,这次主要是为了完成slave复制操作
。10,最后再执行check_cluster,全面检查一次集群状态。包括和前面握手时检查一遍的方法再检查一遍。确认所有的slot都被分配出去了
。11,至此完成了整个创建流程,返回[OK]全部16384个插槽覆盖..

检查检查集群


检查集群状态的命令,没有其他参数,只需要选择一个集群中的一个节点即可。执行命令以及结果如下:

$ ruby​​ redis-trib.rb check 10.180.157.199:6379 
>>>执行集群检查10.180.157.199:6379)
玛:b2506515b38e6bbd3034d540599f4cd2a5279ad1 10.180.157.199:6379 
   插槽:0-5460(5461插槽)主
   1额外副本(S)
小号:d376aaf80de0e01dde1f8cd4647d5ac3317a8641 10.180.157.205:6379 
   插槽:(0插槽)从
   复制e36c46dbe90960f30861af00786d4c2064e63df2 
L:15126fb33796c2c26ea89e553418946f7443d5a5 10.180.157.201:6379 
   插槽:10923-16383(5461插槽)主
   1额外副本(S)
小号:59fa6ee455f58a5076f6d6f83ddd74161fd7fb55 10.180.157.208:6379 
   插槽:(0插槽)从
   复制15126fb33796c2c26ea89e553418946f7443d5a5 
小号:460b3a11e296aafb2615043291b7dd98274bb351 10.180.157.202:6379 
   插槽:(0 slot)slave 
   replicates b2506515b38e6bbd3034d540599f4cd2a5279ad1 
M:e36c46dbe90960f30861af00786d4c2064e63df2 10.180.157.200:6379 
   插槽:5461-10922(5462插槽)master 
   1附加副本
[OK]所有节点同意插槽配置。
>>>检查开槽... 
>>>检查插槽覆盖... 
[OK] 覆盖所有16384个插槽。     
检查前会先执行load_cluster_info_from_node方法,把所有节点数据加载进来.load的方式为通过自己的集群节点发现其他节点,然后连接每个节点,并加入节点数组。

加载完数据,开始检查数据,检查的方式也是调用创建时间使用的check_cluster。

info查看集群信息


然后显示ClusterNode的info_string结果,示例如下:

$ ruby​​ redis-trib.rb info 10.180.157.199:6379 
10.180.157.199:6379( b2506515 ...) - > 0 keys | 5461个插槽| 1个从站。
10.180.157.201:6379(15126fb3 ...) - > 0个键| 5461个插槽| 1个从站。
10.180.157.200:6379(e36c46db ...) - > 0 keys | 5462个插槽| 1个从站。
[OK] 3个主机中的0个键。
平均每个插槽0.00个密钥。

fix修复集群


修复命令的流程跟检查的流程很像,显示加载集群信息,然后在check_cluster方法内传入修正为
真正的变量,会在集群检查出现异常的时候执行修复流程。目前修复命令能修复两种异常,一种是集群有处于迁移中的槽的节点,一种是槽未完全分配的异常

。fix_open_slot方法是修复集群有处理迁移中的槽的节点异常

。1,先检查该槽是谁负责的,迁移的源节点如果没完成迁移,owner还是该节点。没有owner的slot无法完成
修复功能。2,遍历每个节点,获得哪些节点标记该slot为migrating状态,哪些节点标记该slot为importing状态。对于owner不是该节点,但是通过集群countkeysinslot获取到该节点有数据的情况,也认为该节点为importing状态
。3,如果迁移和导入状态的节点均只有1个,这可能是迁移过程中redis-trib.rb被中断所致,直接执行move_slot继续完成迁移任务即可。传递点和固定为
true。4,如果migrating为空,import state state的节点大于0,那么这种情况执行回滚流程,将导入状态的节点数据通过move_slot方法导给slot的所有者节点,传递点,修复和冷为true。接着对importing的节点执行cluster stable命令恢复稳定
。5,如果导入状态的节点为空,有一个迁移状态的节点该节点在当前槽没有数据,那么可以直接把这个槽设为稳定
。6,如果迁移和导入状态不是上述情况,目前redis-trib.rb工具无法修复,上述的三种情况也已经覆盖了通过redis -trib.rb工具迁移出现异常的每个方面,人为的异常情形太多,很难考虑完全
。fix_slots_coverage方法能修复slot未完全分配的异常。未分配的slot有三种状态

。1,所有节点的没有数据。该状态redis-trib.rb工具直接采用随机分配的方式,并没有考虑节点的均衡。本人尝试对没有分配槽的集群通过修复修复集群,结果slot还是能比较平均的分配,但是没有了连续性,打印的槽信息非常离散
。2,有一个节点的该槽有数据。该状态下,直接把槽分配给该槽有数据的节点
。这种情况目前还处于TODO状态,不过redis作者列出了修复的步骤,对这些节点,除第一个节点,执行集群迁移命令,然后把这些节点的数据迁移到第一个节点上。清除迁移状态,然后把slot分配给第一个节点。

reshard在线迁移slot


在线翻译>英语翻译> 

reshard是什么意思reshard是什么意思reshard是什么意思reshard是什么意思reshard是什么意思reshard是什么意思reshard是什么意思reshard是什么意思reshard是什么意思reshard是什么意思reshard是什么意思reshard是什么意思reshard是什么意思reshard是什么

意思reshard, port 
                --from  
                --to  
                --slots  
                --yes 
                --timeout  
                --pipeline  
host:port:这是必传参数,用来从一个节点获取整数集群信息,相当于获得集群信息的入口。 - 
from :需要从哪些源节点上移移,可以从多个源节点完成迁移,以逗号隔开,传递的是节点的节点id,还可以直接传递 - 从所有,这样源节点就是集群的所有节点,不传递该参数的话,则会在迁移过程中提供用户输入。-- 
to :slot需要迁移的目的节点的节点id ,目的节点只能填写一个,不传递该参数的话,则会在移动过程中提示用户输入
。--slots :需要迁移的槽数,不传递该参数的话,则会在迁移过程中提示。用户输入
--yes:设置该参数,可以在打印执行reshard计划的时候,提示用户输入是确认后再执行reshard。
--timeout :设置迁移命令的超时时间
--pipeline :定义集合getkeysinslot命令一次取出的关键数量,不传的话使用默认值为10. 
迁移的流程如下:

1,通过load_cluster_info_from_node方法装载集群信息
。2,执行check_cluster方法检查集群是否健康。只有健康的集群才能进行迁移。
3,获取需要迁移的插槽数量,用户没传递--slots参数,则提示用户手动输入。
4,获取迁移的目的节点,用户没传递--to参数,则提示用户手动输入此处。会检查目的节点必须为主节点
。5,获得迁移的源节点,用户没传递 - 从参数,则提示用户手动输入。此处会检查源节点必须为主节点.--从所有的话,源节点就是除了目的节点外的全部主节点。这里为了保证集群槽分配的平均,建议传递 - 从所有
。6,执行compute_reshard_table方法,计算需要迁移的槽数量如何分配到源节点列表,采用的算法是按照节点负载槽数量由多到少排序,计算每个节点需要迁移的时隙的方法为:迁移时隙数量(this source number)/源节点负责的时隙总数。这样算出的数量可能不为整数,这里代理用下面的方法处理:

n =(numslots / source_tot_slots * s.slots.length)
if i == 0 
    n = n.ceil 
else 
    n = n.floor 
这样的处理方式会带来最终分配插槽与请求迁移的槽数量不一致,这个BUG已经在github上提供作者,https://github.com/antirez/redis/issues/2990。7 

,打印出reshard计划,如果用户没传--yes,就提示用户确认计划
。8,根据reshard计划,一个个槽的迁移到新节点上,迁移使用move_slot方法,该方法被很多命令使用,具体可以参见下面的迁移流程.move_slot方法传递点为true和管道数量
。9,至此,就完成了全部的迁移任务。
下面看下一次reshard的执行结果:

$ ruby​​ redis-trib.rb reshard --from all --to 80b661ecca260c89e3d8ea9b98f77edaeef43dcd --slots 11 10.180.157.199:6379 
>> >表演组检查(使用节点10.180.157.199:6379)
š:b2506515b38e6bbd3034d540599f4cd2a5279ad1 10.180.157.199:6379 
   插槽:(0插槽)从
   复制460b3a11e296aafb2615043291b7dd98274bb351 
小号:d376aaf80de0e01dde1f8cd4647d5ac3317a8641 10.180.157.205:6379 
   插槽:(0插槽)从
   复制e36c46dbe90960f30861af00786d4c2064e63df2 
L:15126fb33796c2c26ea89e553418946f7443d5a5 10.180.157.201:6379 
   插槽:10923-16383(5461插槽)主
   1额外副本(S)
小号:59fa6ee455f58a5076f6d6f83ddd74161fd7fb55 10.180.157.208:6379 
   插槽:(0插槽)从
   复制15126fb33796c2c26ea89e553418946f7443d5a5 
L:460b3a11e296aafb2615043291b7dd98274bb351 10.180.157.202:6379 
   插槽:0- 5460(5461插槽)主
   1额外副本(S)
L:80b661ecca260c89e3d8ea9b98f77edaeef43dcd 10.180.157.200:6380 
   插槽:(0插槽)主
   0额外的副本(S)
L:e36c46dbe90960f30861af00786d4c2064e63df2 10.180.157.200:6379 
   插槽:5461-10922(5462插槽)主机
   1附加副本
[OK]所有节点都同意有关插槽配置。
>>>检查开放插槽... 
>>>检查插槽覆盖... 
[OK]覆盖所有16384个插槽。

准备移动11个插槽。
  来源节点:
    L:15126fb33796c2c26ea89e553418946f7443d5a5 10.180.157.201:6379 
   插槽:10923-16383(5461插槽)主
   1额外副本(S)
    L:460b3a11e296aafb2615043291b7dd98274bb351 10.180.157.202:6379 
   插槽:0-5460(5461插槽)主
   1额外副本(S )
    玛:e36c46dbe90960f30861af00786d4c2064e63df2 10.180.157.200:6379 
   插槽:5461-10922(5462插槽)主
   1额外副本(S)
  目标节点:
    L:80b661ecca260c89e3d8ea9b98f77edaeef43dcd 10.180.157.200:6380 
   插槽:(0插槽)主
   0额外的副本(S)
  Resharding计划:
    从e36c46dbe90960f30861af00786d4c2064e63df2移动槽5461 
    从e36c46dbe90960f30861af00786d4c2064e63df2移动槽5462 
    从e36c46dbe90960f30861af00786d4c2064e63df2移动槽5463 
    从e36c46dbe90960f30861af00786d4c2064e63df2移动槽5464 
    从460b3a11e296aafb2615043291b7dd98274bb351移动插槽0 
    从460b3a11e296aafb2615043291b7dd98274bb351移动插槽1 
    移动插槽2从460b3a11e296aafb2615043291b7dd98274bb351 
    从15126fb33796c2c26ea89e553418946f7443d5a5移动插槽10923 
    移动插槽10924从15126fb33796c2c26ea89e553418946f7443d5a5 
    移动插槽10925从15126fb33796c2c26ea89e553418946f7443d5a5 
您要继续执行建议的转发计划(是/否)吗?yes 
将时隙5461从10.180.157.200:6379 
移动到10.180.157.200:6380:将时隙5462从10.180.157.200:6379 
移动到10.180.157.200:6380:将时隙5463从10.180.157.200:6379 
移动到10.180.157.200:6380:移动时隙5464从10.180.157.200:6379到10.180.157.200:6380:
将时隙0从10.180.157.202:6379 
移动到10.180.157.200:6380:将时隙1从10.180.157.202:6379 
移动到10.180.157.200:6380:移动时隙2从10.180.157.202:6379到10.180.157.200:6380:
将时隙10923从10.180.157.201:6379移动到10.180.157.200:6380:将时隙10924从10.180.157.201:6379 
移动到10.180.157.200:6380:
将时隙10925从10.180 .157.201:6379 to 10.180.157.200:6380:move_slot 
方法可以在线将一个槽的全部数据从源节点迁移到目的节点,fix,reshard,rebalance都需要调用该方法迁移

slot。move_slot接受下面几个参数,

1 ,管道:设置一次从插槽上获取多少个键。
2,安静:迁移会打印相关信息,设置安静的参数,可以不用打印这些信息。
3,冷:设置冷,会忽略执行导入和迁移
4,点:设置点,则会在迁移过程打印迁移键数量的进度
。5,更新:设置更新,则会更新内存信息,方便以后的操作
。move_slot流程如下:

1,如果没有设置cold,则对源节点执行cluster importing命令,对目的节点执行migrating命令.fix的时候有可能导入和迁移已经执行过来,所以这种场景会设置
cold。2,通过cluster getkeysinslot命令,一次性获取远程点数量。
3,对于这些键执行迁移命令,将数据从源节点迁移到目的节点
。4,如果迁移出现异常,在固定模式下,BUSYKEY的异常,会使用迁移的替换模式再执行一次,BUSYKEY表示目的节点已经有该按键了,替换模式可以强制替换目的节点的关键。不是固定模式就直接返回错误了。
5,循环执行集群getkeysinslot命令,直到返回的关键数量为0,就退出循环。
6,如果没有设置冷,对每个节点执行cluster setslot命令,将槽赋予目的节点
。7,如果设置更新,则修改源节点和目的节点的slot信息
。8,至此完成了迁移slot的流程。

rebalance平衡集群


重新平衡命令可以根据用户传入的参数平衡集群节点的插槽数量,平衡功能非常强大,可以传入的参数很多,以下是再平衡的参数列表和命令示例。

重新平衡主机:端口
                --weight  
                -自动加权 - 
                阈值 
                --use-empty-masters 
                --timeout  
                --simulate 
                --pipeline  

$ ruby​​ redis-trib.rb rebalance --threshold 1 - weight b31e3a2e = - weight 60b8e3a1 = 5 --use-empty-masters --simulate 10.180.157.199:6379 
下面也先一一解释下每个参数的用法:

host:port:这个是必传参数,用来从一个节点获取整个- 
weight :节点的权重,格式为node_id = weight,如果需要为多个节点分配权重的话,需要添加多个--weight 参数,即 - weight b31e3a2e = 5 --weight 60b8e3a1 = 5,node_id可为节点名称的前缀,只要保证前缀位数能唯一区分该节点即可。--auto没有传递权重的节点的权重默认为1. 
--auto -weights:这个参数在rebalance流程中并未用到。-- 
threshold :只有节点需要迁移的槽口阈值超过阈值,才会执行rebalance操作。具体计算方法可以参考下面的rebalance命令流程的第四。步
--use-空大师:重新平衡是否考虑没有节点的主,默认没有分配插槽节点的高手是不参与重新平衡的,设置--use-空大师可以让没有分配时隙的节点参与再平衡
- -timeout :设置迁移命令的超时时间
。--simulate:设置该参数,可以模拟rebalance操作,提示用户会迁移哪些slot,而不会真正执行迁移操作
。--pipeline :with reshar的流水线参数一样,定义集合getkeysinslot命令一次取出的关键数量,不传的话使用默认值为10. 
rebalance命令流程如下:

1,load_cluster_info_from_node方法先加载集群信息
。2,计算每个master的权重,根据参数 - - weight ,为每个设置的节点分配权重,没有设置的节点,then权重默认为1. 
3,根据每个master的权重,以及总的权重,计算自己期望被分配多少个slot。的方法为:总槽数量(自己的权重/总权重)
。4,计算每个主期望分配的槽是否超过设置的阈值,即--threshold 设置的阈值或者默认的阈值。方法为:先计算期望移动节点的阈值,算法为:(100-(100.0 * expected / n.slots.length))abs,如果计算出的阈值没有超出设置阈值,则不需要为该节点移动slot 。只要有一个主的移动节点超过阈值,就会触发rebalance操作
。5,如果触发了rebalance操作。那么就开始执行rebalance操作,先让每个节点当前分配的槽数量减去期望分配的槽数量获得将每个节点的平衡从小到大进行
排序获得sn数组。6,使用dst_idx和src_idx游标分别从sn数组的头部和尾部开始遍历。目的是为了把尾部节点的槽分配给头部节点。

SN数组保存的平衡列表排序后,负数在前面,正数在后面。负数表示需要有槽迁入,所以使用dst_idx游标,正数表示需要有槽迁出,所以使用src_idx游标。理论上SN数组各节点的平衡值加起来应该为0,不过由于在计算期望分配的槽的时候只使用直接取整的方式,所以可能出现平衡值之和不为0的情况,平衡值之和不为0即为节点不平衡的槽数量,由于槽总数有16384个,不平衡数量相对总数,基数很小,所以对rebalance流程影响不大

。7,获取sn [dst_idx]和sn [src_idx]小的那个值,该值即为需要从sn [src_idx]节点迁移到sn [dst_idx]节点的槽数量
。8,接着通过compute_reshard_table方法计算源节点的槽如何分配到源节点列表。这个方法在reshard流程中,也有调用,具体步骤可以参考reshard流程的第六步
。9,如果是模拟模式,则只是打印出迁移列表
。10,如果没有设置模拟,则执行move_slot操作,安静=>真实的,:点=>假:更新=>真
。11,迁移完成后更新SN [dst_idx]和SN [src_idx]的平衡值如果平衡值为0后,游标向前进1。
12,直到dst_idx到达src_idx游标,完成整个rebalance操作。

add-node将新节点加入集群


添加节点命令可以将新节点加入集群,节点可以为大师,也可以为某个主节点的奴隶。

添加节点new_host:new_port existing_host:existing_port 
          --slave 
          --master-ID  
添加节点有两个可选参数:--slave 

:设置该参数,则新节点以slave的角色加入集群
--master-id:这个参数需要设置了--slave才能生效, - master-id用来指定新节点的主节点。如果不设置该参数,则会随机为节点选择主节点。
可以看下add-node命令的执行示例:

$ ruby​​ redis-trib.rb add-node --slave --master-id dcb792b3e85726f012e83061bf237072dfc45f99 10.180 .157.202:6379 10.180.157.199:6379 
>>>将节点10.180.157.202:6379添加到集群10.180.157.199:6379 
>>>执行集群检查(使用节点
10.180.157.199:6379)M:dcb792b3e85726f012e83061bf237072dfc45f99 10.180.157.199:6379 
   插槽:0-5460(5461个时隙)主机
   0个附加副本
M:464d740bf48953ebcf826f4113c86f9db3a9baf3 10.180.157.201:6379 
   时隙:10923-16383(5461个时隙)主机
   0个附加副本
M:befa7e17b4e5f239e519bc74bfef3264a40f96ae 10.180.157.200:6379 
   插槽:5461 -10922(5462个插槽)主机
   0个附加副本
[OK]所有节点都同意有关插槽配置。
>>>检查开放插槽... 
>>>检查插槽覆盖... 
[OK]覆盖所有16384个插槽。
>>>发送CLUSTER MEET到节点10.180.157.202:6379,使其加入集群。
等待集群加入。
>>>将节点配置为10.180.157.199:6379的副本。
[OK]新节点正确添加。
add-node流程如下:

1,通过load_cluster_info_from_node方法转载集群信息,check_cluster方法检查集群是否健康
。2,如果设置了--slave,则需要为该节点寻找master节点。设置了--master-id,该节点作为新节点的主节点,如果没有设置--master-id,则调用get_master_with_least_replicas方法,寻找slave数量最少的主节点如果slave数量一致,则选择load_cluster_info_from_node顺序发现的第一个节点.load_cluster_info_from_node顺序的第一个节点是添加节点设置的existing_host:existing_port节点,后面的顺序根据在该节点执行群集节点返回的结果返回的节点顺序
。3,连接新的节点并与集群第一个节点握手
4,如果没有设置-slave就直接返回ok,设置了-slave,则需要等待确认新节点加入集群,然后执行cluster replicate命令复制master节点
。5,至此,完成了全部的增加节点的流程。

从集群中删除节点


删除命令传递两个参数:

host:port:从该节点获取集群信息
node_id:需要删除的节点id 。
德尔节点的执行结果示例如下:

$红宝石Redis的-trib.rb德尔节点10.180.157.199:6379 d5f6d1d17426bd564a6e309f32d0f5b96962fe53 
>>>从集群中删除10.180.157.199:6379节点d5f6d1d17426bd564a6e309f32d0f5b96962fe53 
>>>发送CLUSTER忘记消息集群.. 。
>>> SHUTDOWN节点。
del节点流程如下:

1,通过load_cluster_info_from_node方法转载集群信息
。2,根据传入的节点id获取节点,如果节点没找到,则直接提示错误并退出
。3,如果节点分配的slot不为空,则直接提示错误并退出
。4,遍历集群内的其他节点,执行集群忘了命令,从每个节点中去除该节点如果删除的节点是主,而且它有奴隶的话,这些奴隶会去复制其他主,调用的方法是get_master_with_least_replicas,与add-node没设置--master-id寻找master的方法一样。

5,然后关闭该节点


set-timeout设置集群节点间心跳连接的超时时间

set-timeout用于设置集群节点间心跳连接的超时时间,单位是毫秒,不得小于100毫秒,因为100毫秒对于心跳时间来说太短了。该命令修改是节点配置参数cluster-node-timeout,默认是15000毫秒。通过该命令,可以给每个节点设置超时时间,设置的方式使用配置设置命令动态设置,然后执行配置重写命令将配置持久化保存到硬盘。以下是示例:

ruby redis-trib.rb set-timeout 10.180.157.199:6379 30000 
>>>在每个群集节点中重新配置节点超时... 
***为10.180.157.199:6379 
设置新的超时
*** 为10.180.157.205:6379设置新的超时***新的超时设置为10.180.157.201:6379 
***新超时设置为10.180.157.200:6379 
***新超时设置为10.180.157.208:6379 
>>>新节点超时设置。5 OK,0 ERR。

call in集群全部节点上执行命令


call 

ruby redis-trib.rb call。call command commands 可以用来在集群的全部节点执行相同的命令.call命令也是需要通过集群的一个节点地址,连上整个集群,然后在集群的每个节点执行该命令。10.180.157.199:6379 get key 
>>>调用GET键
10.180.157.199:6379:MOVED 12539 
10.180.157.201:6379 10.180.157.205:6379:MOVED 12539 
10.180.157.201:6379 
10.180.157.201:6379:10.180.157.200:6379 :MOVED 12539 10.180.157.201:6379 
10.180.157.208:6379:MOVED 12539 10.180.157.201:6379

import将外部redis数据导入集群


导入命令可以把外部的redis节点数据导入集群。导入的流程如下:

1,通过load_cluster_info_from_node方法转载集群信息,check_cluster方法检查集群是否健康
。2,连接外部redis节点,如果外部节点开启cluster_enabled,则提示错误。
3,通过扫描命令遍历外部节点,一次获取1000条数据。
4,遍历这些键,计算出密钥对应的插槽。
5,执行迁移命令,源节点是外部节点,目的节点是集群插槽对应的节点,如果设置了--copy参数,则传递复制参数,如果设置了--replace,则传递替换参数
。6,不停执行扫描命令,直到遍历完全部分的关键
。7,至此完成整个迁移流程
这中间如果出现异常,程序就会停止。没有使用--copy模式,则可以重新执行import命令,使用--copy的话,最好清空新的集群再导入一次。

导入命令更适合离线的把外部Redis数据导入,在线导入的话最好使用更专业的导入工具,以从属的方式连接redis节点去同步节点数据应该是更好的方式。

下面是一个例子

./redis-trib.rb import --from 10.0.10.1:6379 10.10.10.1:7000上面
的命令是把10.0.10.1:6379(redis 2.8)上的数据导入到10.10.10.1:7000这个节点所在的集群

你可能感兴趣的:(NoSql)