原文链接:http://blog.csdn.net/xyang81/article/details/51895011
在上一篇《Redis3.2集群担建与验证》文章中分享了集群的详细担建过程,本篇主要分享集群管理的常见操作,如:添加节点、删除节点、slot分配。如果你还没有担建集群环境,建议先看上篇《Redis3.2集群担建与验证》过程,再来阅读本文比较好理解。
1、集群管理常用命令
// 集群(cluster)
CLUSTER INFO 打印集群的状态信息
CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息
// 节点(node)
CLUSTER MEET <ip> <port> 将ip和port所指定的节点添加到集群当中,让它成为集群的一份子
CLUSTER FORGET <node_id> 从集群中移除node_id指定的节点
CLUSTER REPLICATE <node_id> 将当前节点设置为node_id指定节点的从节点
CLUSTER SAVECONFIG 将当前节点的配置信息手动保存到硬盘(nodes-port.conf)
CLUSTER SLAVES <master_node_id> 查询指定的master_node_id主节点有哪些从(slave)节点
// 槽(slot)
CLUSTER ADDSLOTS <slot> [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点
CLUSTER DELSLOTS <slot> [slot ...] 将一个或多个槽从当前节点移除
CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点
CLUSTER SETSLOT <slot> NODE <node_id> 将当前节点指定的槽(slot)指派给node_id指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽,然后再进行指派
CLUSTER SETSLOT <slot> MIGRATING <node_id> 将当前节点指定的槽(slot)迁移到node_id指定的节点中
CLUSTER SETSLOT <slot> IMPORTING <node_id> 从node_id指定节点中的槽(slot)导入到当前节点
CLUSTER SETSLOT <slot> STABLE 取消对当前节点指定槽(slot)的导入(import)或者迁移(migrate)
CLUSTER SLOTS 查看槽(slot)在集群中的分配情况
// 键 (key)
CLUSTER KEYSLOT <key> 计算键key应该被分配在哪个槽上
CLUSTER COUNTKEYSINSLOT <slot> 返回指定槽(slot)保存key的数量
CLUSTER GETKEYSINSLOT <slot> <count> 获取指定槽(slot)中count个key,如果指定槽中大于count个key,则只返回前cout个key,小于或为空,则返回最多数量的key
以上命令是集群特有的,必须登录到redis集群才能使用。注释中提到的当前节点,指登录到集群中指定的节点。如:redis-cli -h 192.168.0.201 -p 6379
,当前登录的节点就是192.168.0.201:6379。
更多集群管理命令请参考官网:http://redis.io/commands/cluster-addslots
shell> redis-cli -c -h 192.168.0.201 -p 6379
127.0.0.1:6379> cluster nodes
459dbcccc1e5be021f19efde794b9e84474c0c02 192.168.0.202:16379 slave b6814c717080de33907e6f769e1fd8dc4fe53c38 0 1468339459776 11 connected
06023f8283389ad5580c782797f49a5996c108b3 192.168.0.201:6379 myself,master - 0 0 10 connected 500-11255
91179b96d9b8abce85fa7a5748aa9b4114f0b260 192.168.0.202:16380 slave 06023f8283389ad5580c782797f49a5996c108b3 0 1468339462797 10 connected
ef8a49e5242c791551f1b317d5039144e38acde6 192.168.0.201:6380 slave 13567f6f8787d3aa3f4ef3abd15c2cc500a1469b 0 1468339466819 8 connected
b6814c717080de33907e6f769e1fd8dc4fe53c38 192.168.0.201:6381 master - 0 1468339465813 11 connected 0-499
13567f6f8787d3aa3f4ef3abd15c2cc500a1469b 192.168.0.202:16381 master - 0 1468339463802 8 connected 11256-16383
2、添加节点
添加一对(一主一从)新的节点加入到集群当中:192.168.0.201:6382(Master)和192.168.0.201:6383(Slave),文中简称201:6381和201:16382。节点添加方式请参考《Redis3.2集群担建与验证》
1> 添加master节点
shell> redis-trib.rb add-node 192.168.0.201:6382 192.168.0.201:6379
参数说明:
192.168.0.201:6382:新节点
192.168.0.201:6379:可以是集群中的任意一个节点(这里以201:6379为例)
注意:
1> 新的节点必须开启了集群配置
2> 新的节点必须已启动
如果不同时满足以上两点,将无法加入到集群中。成功加入集群后,会打印如下信息:
2> 为master节点分配slot
当往Redis集群中存储一份数据时,redis根据key的hash值对16384(slot)取模,算出负责指定slot范围内的某个节点来存储这个key。集群在第一次创建的时候,会给每个master节点在16384个slot中平均分配相应的slot数量,而后面新加入的master节点默认是不会分配slot的。所以我们需要手动为新加入的节点分配一定范围的slot,以便集群在存取数据的时候,能够找到这个新加入的节点。
[[email protected] redis-3.2.0]# redis-cli cluster nodes
901cade1bc2703ef2bb4ff49466b38762346755d 192.168.0.201:6382 master - 0 1468324422110 0 connected
06023f8283389ad5580c782797f49a5996c108b3 192.168.0.201:6379 myself,master - 0 0 1 connected 0-5460
...
sloat范围显示在节点状态(connected)后边,从上可以看出,新加入的节点201:6382是没有分配slot的,所以为空。而为201:6379节点分配了0-5460范围的slot。
为新节点分配slot的原理是从其它主节点中负责的slot中,各移出一部份
slot给新的节点。下面为201:6382分配slot:
shell> redis-trib.rb reshard 192.168.0.201:6382
注意上图中红框部份:
1> 1000 : 为新的master节点分配1000个slot
2> 901cade1bc2703ef2bb4ff49466b38762346755d:接收1000个slot的master节点ID
3> 选择从哪些主节点移动slot到新加入的主节点中:
* all:表示从集群中所有master节点中各移动一部份slot,凑够1000个slot为止
* 选择输入一个或多个master的node_id来从中移动,最后输入done完成选择
4> yes:执行slot移动操作,输入no表示终止操作。
下面看下新的集群节点及slot分布情况:
[[email protected] redis-3.2.0]# redis-cli cluster nodes
901cade1bc2703ef2bb4ff49466b38762346755d 192.168.0.201:6382 master - 0 1468325773988 9 connected 0-332 5461-5794 10923-11255
459dbcccc1e5be021f19efde794b9e84474c0c02 192.168.0.202:16379 slave b6814c717080de33907e6f769e1fd8dc4fe53c38 0 1468325769968 7 connected
06023f8283389ad5580c782797f49a5996c108b3 192.168.0.201:6379 myself,master - 0 0 1 connected 333-5460
91179b96d9b8abce85fa7a5748aa9b4114f0b260 192.168.0.202:16380 slave 06023f8283389ad5580c782797f49a5996c108b3 0 1468325775495 5 connected
ef8a49e5242c791551f1b317d5039144e38acde6 192.168.0.201:6380 slave 13567f6f8787d3aa3f4ef3abd15c2cc500a1469b 0 1468325772982 8 connected
b6814c717080de33907e6f769e1fd8dc4fe53c38 192.168.0.201:6381 master - 0 1468325771976 7 connected 5795-10922
13567f6f8787d3aa3f4ef3abd15c2cc500a1469b 192.168.0.202:16381 master - 0 1468325774992 8 connected 11256-16383
已经成功为201:6382节点分配了0-332、5461-5794、10923-11255范围的slot,可以看出redis从其它三个master节点中均匀的移动了一部份slot到201:6382中。
3> 添加slave节点
下面为201:6382 master节点添加一个slave节点201:6383
shell> redis-trib.rb add-node --slave --master-id 901cade1bc2703ef2bb4ff49466b38762346755d 192.168.0.201:6383 192.168.0.201:6379
参数说明:
1> –slave:表示添加从节点
2> –master-id:master节点ID,这里用上边新添加的主节点ID(201:6382)
3> 192.168.0.201:6383:新slave节点的IP和端口
4> 192.168.0.201:6379:集群中任意旧节点,只要能连上就可以。这里以201:6379为例
添加slave节点成功后集群中的节点状态:
[[email protected] redis-3.2.0]# redis-cli cluster nodes
901cade1bc2703ef2bb4ff49466b38762346755d 192.168.0.201:6382 master - 0 1468333842665 9 connected 0-332 5461-5794 10923-11255
459dbcccc1e5be021f19efde794b9e84474c0c02 192.168.0.202:16379 slave b6814c717080de33907e6f769e1fd8dc4fe53c38 0 1468333841661 7 connected
9080c5049615730c66731b54cb084999009eeb52 192.168.0.201:6383 slave 901cade1bc2703ef2bb4ff49466b38762346755d 0 1468333843669 9 connected
06023f8283389ad5580c782797f49a5996c108b3 192.168.0.201:6379 myself,master - 0 0 1 connected 333-5460
91179b96d9b8abce85fa7a5748aa9b4114f0b260 192.168.0.202:16380 slave 06023f8283389ad5580c782797f49a5996c108b3 0 1468333844674 5 connected
ef8a49e5242c791551f1b317d5039144e38acde6 192.168.0.201:6380 slave 13567f6f8787d3aa3f4ef3abd15c2cc500a1469b 0 1468333842665 8 connected
b6814c717080de33907e6f769e1fd8dc4fe53c38 192.168.0.201:6381 master - 0 1468333845678 7 connected 5795-10922
13567f6f8787d3aa3f4ef3abd15c2cc500a1469b 192.168.0.202:16381 master - 0 1468333846685 8 connected 11256-16383
very good~ 可以看出,201:6383以成功添加为一个slave节点,并将201:6382作为master节点。
cluster nodes
命令列表的节点状态信息说明:
459dbcccc1e5be021f19efde794b9e84474c0c02 192.168.0.202:16379 slave b6814c717080de33907e6f769e1fd8dc4fe53c38 0 1468333841661 7 connected
1> 459dbcccc1e5be021f19efde794b9e84474c0c02 :节点ID
2> 192.168.0.202:16379:节点IP和端口
3> slave:节点类型,master、slave或myself(master/slave)
4> b6814c717080de33907e6f769e1fd8dc4fe53c38 :master节点ID,如果自己是master节点,这一列的值为0
5> 0:集群最近一次向节点发送 PING 命令之后, 过去了多长时间还没接到回复。
6> 1468333841661:节点最近一次返回 PONG 回复的时间
7> 7:节点的配置纪元
8> connected:节点网络连接状态
9> 如果是主节点,节点状态后边显示slot分配的范围
3、改变slave节点的master
将上边新加的slave节点(201:6383)的master,修改为201:6379(06023f8283389ad5580c782797f49a5996c108b3)
shell> redis-cli -h 192.168.0.201 -p 6383 cluster nodes | grep myself
9080c5049615730c66731b54cb084999009eeb52 192.168.0.201:6383 myself,slave 901cade1bc2703ef2bb4ff49466b38762346755d 0 0 0 connected
当前slave节点201:6383的master节点是901cade1bc2703ef2bb4ff49466b38762346755d
shell> redis-cli -h 192.168.0.201 -p 6383
192.168.0.201:6383> cluster replicate 06023f8283389ad5580c782797f49a5996c108b3
06023f8283389ad5580c782797f49a5996c108b3:新master节点的ID
192.168.0.201:6383> CLUSTER SLAVES 06023f8283389ad5580c782797f49a5996c108b3
1) "91179b96d9b8abce85fa7a5748aa9b4114f0b260 192.168.0.202:16380 slave 06023f8283389ad5580c782797f49a5996c108b3 0 1468336124600 1 connected"
2) "9080c5049615730c66731b54cb084999009eeb52 192.168.0.201:6383 myself,slave 06023f8283389ad5580c782797f49a5996c108b3 0 0 0 connected"
可以看出201:6383 slave节点已经是201:6379 master节点的子节点了。
4、删除节点
1> 删除slave节点
[root@localhost redis-3.2.0]# redis-trib.rb del-node 192.168.0.201:6383 9080c5049615730c66731b54cb084999009eeb52
>>> Removing node 9080c5049615730c66731b54cb084999009eeb52 from cluster 192.168.0.201:6383
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
参数说明:
1> del-node:删除节点参数
2> 192.168.0.201:6383:节点IP和端口
3> 9080c5049615730c66731b54cb084999009eeb52:节点ID
节点成功删除后,会同时将进程杀死
从节点重新恢复后,先cluster meet ip port
将从节点加入集群,然后设置自己的mastercluster replication master_node_id
2、删除master节点
注意:
1> 如果master节点有slot,必须先将所有slot分配给其它master节点。否则会提示你先将slot移除再尝试删除,如下所示:
shell> redis-trib.rb del-node 192.168.0.201:6382 901cade1bc2703ef2bb4ff49466b38762346755d
>>> Removing node 901cade1bc2703ef2bb4ff49466b38762346755d from cluster 192.168.0.201:6382
[ERR] Node 192.168.0.201:6382 is not empty! Reshard data away and try again.
2> 如果master节点有slave节点,先将slave节点移到其它master下
- 移除201:6382 master节点的slot
[[email protected] redis-3.2.0]# redis-trib.rb reshard 192.168.0.201:6382
>>> Performing Cluster Check (using node 192.168.0.201:6382)
M: 901cade1bc2703ef2bb4ff49466b38762346755d 192.168.0.201:6382
slots:0-332,5461-5794,10923-11255 (1000 slots) master
1 additional replica(s)
M: 06023f8283389ad5580c782797f49a5996c108b3 192.168.0.201:6379
slots:333-5460 (5128 slots) master
1 additional replica(s)
...
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 1000 # 201:6382一共1000个slot
What is the receiving node ID? 06023f8283389ad5580c782797f49a5996c108b3 # 接收这1000个slot的节点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.
Source node #1:901cade1bc2703ef2bb4ff49466b38762346755d # 移除这1000个slot的master节点ID(这里同样是201:6382)
Source node #2:done
....
Do you want to proceed with the proposed reshard plan (yes/no)? yes
新增master节点后,也进行了这一步操作,当时是分配,现在是去掉,反着的。
- 删除master节点
shell> redis-trib.rb del-node 192.168.0.201:6382 901cade1bc2703ef2bb4ff49466b38762346755d
>>> Removing node 901cade1bc2703ef2bb4ff49466b38762346755dfrom cluster 192.168.0.201:6382
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
此时新的master节点也被删除了,回到了添加节点之前的状态。