Redis 3.0 之后支持了 Cluster,大大增强了 Redis 水平扩展的能力。Redis Cluster 是 Redis 官方的集群实现方案,在此之前已经有第三方 Redis 集群解决方案,如 Twenproxy、Codis,与其不同的是:Redis Cluster 并非使用 Porxy 的模式来连接集群节点,而是使用无中心节点的模式来组建集群。在 Cluster 出现之前,只有保证了 Redis 的高可用性。
Redis Cluster 实现在多个节点之间进行数据共享,即使部分节点失效或者无法进行通讯时,Cluster 仍然可以继续处理请求。若每个主节点都有一个从节点支持,在主节点下线或者无法与集群的大多数节点进行通讯的情况下, 从节点提升为主节点,并提供服务,保证 Cluster 正常运行,Redis Cluster 的节点分片是通过哈希槽(hash slot)实现的,每个键都属于这 16384(0~16383) 个哈希槽的其中一个,每个节点负责处理一部分哈希槽。
Ubuntu 14.04
Redis 3.2.8
主节点:192.168.100.134/135/136:7021
从节点:192.168.100.134/135/136:7022
对应主从节点:
- 主 从
- 134:7021 135:7022
- 135:7021 136:7022
- 136:7021 134:7022
①:安装
按照文章中的说明,装好 Redis。只需要修改一下 Cluster 相关的配置参数:
View Code
- ################################ REDIS CLUSTER ###############################
- #集群开关,默认是不开启集群模式。
- cluster-enabled yes
- #集群配置文件的名称,每个节点都有一个集群相关的配置文件,持久化保存集群的信息。这个文件并不需要手动配置,这个配置文件有Redis生成并更新,每个Redis集群节点需要一个单独的配置文件,请确保与实例运行的系统中配置文件名称不冲突
- cluster-config-file nodes-7021.conf
- #节点互连超时的阀值。集群节点超时毫秒数
- cluster-node-timeout 30000
- #在进行故障转移的时候,全部slave都会请求申请为master,但是有些slave可能与master断开连接一段时间了,导致数据过于陈旧,这样的slave不应该被提升>为master。该参数就是用来判断slave节点与master断线的时间是否过长。判断方法是:
- #比较slave断开连接的时间和(node-timeout * slave-validity-factor) + repl-ping-slave-period
- #如果节点超时时间为三十秒, 并且slave-validity-factor为10,假设默认的repl-ping-slave-period是10秒,即如果超过310秒slave将不会尝试进行故障转移
- #可能出现由于某主节点失联却没有从节点能顶上的情况,从而导致集群不能正常工作,在这种情况下,只有等到原来的主节点重新回归到集群,集群才恢复运作
- #如果设置成0,则无论从节点与主节点失联多久,从节点都会尝试升级成主节
- cluster-slave-validity-factor 10
- #master的slave数量大于该值,slave才能迁移到其他孤立master上,如这个参数若被设为2,那么只有当一个主节点拥有2 个可工作的从节点时,它的一个从节>点会尝试迁移。
- #主节点需要的最小从节点数,只有达到这个数,主节点失败时,它从节点才会进行迁移。
- # cluster-migration-barrier 1
- #默认情况下,集群全部的slot有节点分配,集群状态才为ok,才能提供服务。设置为no,可以在slot没有全部分配的时候提供服务。不建议打开该配置,这样会
- 造成分区的时候,小分区的master一直在接受写请求,而造成很长时间数据不一致。
- #在部分key所在的节点不可用时,如果此参数设置为"yes"(默认值), 则整个集群停止接受操作;如果此参数设置为"no",则集群依然为可达节点上的key提供读>操作
- cluster-require-full-coverage yes
安装好之后开启 Redis:均运行在集群模式下
- root@redis-cluster1:~# ps -ef | grep redis
- redis 4292 1 0 00:33 ? 00:00:03 /usr/local/bin/redis-server 192.168.100.134:7021 [cluster]
- redis 4327 1 0 01:58 ? 00:00:00 /usr/local/bin/redis-server 192.168.100.134:7022 [cluster]
②:配置主节点
添加节点: cluster meet ip port
- 进入其中任意7021端口的实例,进入集群模式需要参数-c:
- ~# redis-cli -h 192.168.100.134 -p 7021 -c
- 192.168.100.134:7021> cluster meet 192.168.100.135 7021
- OK
- 192.168.100.134:7021> cluster meet 192.168.100.136 7021
- OK
- 节点添加成功
查看集群状态:cluster info
- 192.168.100.134:7021> cluster info
- cluster_state:fail #集群状态
- cluster_slots_assigned:0 #被分配的槽位数
- cluster_slots_ok:0 #正确分配的槽位
- cluster_slots_pfail:0
- cluster_slots_fail:0
- cluster_known_nodes:3 #当前3个节点
- cluster_size:0
- cluster_current_epoch:2
- cluster_my_epoch:1
- cluster_stats_messages_sent:83
- cluster_stats_messages_received:83
上面看到集群状态是失败的,原因是槽位没有分配,而且需要一次性把 16384 个槽位完全分配了,集群才可用。接着开始分配槽位:需要登入到各个节点,进行槽位的分配,如:
node1 分配:0~5461
node2 分配:5462~10922
node3 分配:10923~16383
分配槽位:cluster addslots 槽位,一个槽位只能分配一个节点,16384 个槽位必须分配完,不同节点不能冲突。
- 192.168.100.134:7021> cluster addslots 0
- OK
- 192.168.100.135:7021> cluster addslots 0 #冲突
- (error) ERR Slot 0 is already busy
目前还没有支持区间范围的添加槽位操作,所以添加 16384 个槽位的需要写一个批量脚本(addslots.sh):
- node1:
- #!/bin/bash
- n=0
- for ((i=n;i<=5461;i++))
- do
- /usr/local/bin/redis-cli -h 192.168.100.134 -p 7021 -a dxy CLUSTER ADDSLOTS $i
- done
- node2:
- #!/bin/bash
- n=5462
- for ((i=n;i<=10922;i++))
- do
- /usr/local/bin/redis-cli -h 192.168.100.135 -p 7021 -a dxy CLUSTER ADDSLOTS $i
- done
- node3:
- #!/bin/bash
- n=10923
- for ((i=n;i<=16383;i++))
- do
- /usr/local/bin/redis-cli -h 192.168.100.136 -p 7021 -a dxy CLUSTER ADDSLOTS $i
- done
连接 3 个节点分别执行:bash addslots.sh。所有槽位得到分配之后,在看下集群状态:
- 192.168.100.134:7021> cluster info
- cluster_state:ok
- cluster_slots_assigned:16384
- cluster_slots_ok:16384
- cluster_slots_pfail:0
- cluster_slots_fail:0
- cluster_known_nodes:3
- cluster_size:3
- cluster_current_epoch:2
- cluster_my_epoch:1
- cluster_stats_messages_sent:4193
- cluster_stats_messages_received:4193
看到集群已经成功,那移除一个槽位看看集群会怎么样:cluster delslots 槽位
- 192.168.100.134:7021> cluster delslots 0
- OK
- 192.168.100.134:7021> cluster info
- cluster_state:fail
- cluster_slots_assigned:16383
- cluster_slots_ok:16383
- cluster_slots_pfail:0
- cluster_slots_fail:0
- cluster_known_nodes:3
- cluster_size:3
- cluster_current_epoch:2
- cluster_my_epoch:1
- cluster_stats_messages_sent:4482
- cluster_stats_messages_received:4482
看到 16384 个槽位如果没有分配完全,集群是不成功的。 到这里为止,一个简单的 Redis Cluster 已经搭建完成,这里每个节点都是一个单点,若出现一个节点不可用,会导致整个集群的不可用,如何保证各个节点的高可用呢?这可以对每个主节点再建一个从节点来保证。
添加从节点(集群复制): 复制的原理和单机的 Redis 复制原理一样,区别是:集群下的从节点也需要运行在 cluster 模式下,要先添加到集群里面,再做复制。
①:添加从节点到集群中
- 192.168.100.134:7021> cluster meet 192.168.100.134 7022
- OK
- 192.168.100.134:7021> cluster meet 192.168.100.135 7022
- OK
- 192.168.100.134:7021> cluster meet 192.168.100.136 7022
- OK
- 192.168.100.134:7021> cluster info
- cluster_state:ok
- cluster_slots_assigned:16384
- cluster_slots_ok:16384
- cluster_slots_pfail:0
- cluster_slots_fail:0
- cluster_known_nodes:6 #当前集群下的所有节点,包括主从节点
- cluster_size:3 #当前集群下的有槽位分配的节点,即主节点
- cluster_current_epoch:5
- cluster_my_epoch:1
- cluster_stats_messages_sent:13438
- cluster_stats_messages_received:13438
②:创建从节点 cluster replicate node_id ,通过 cluster nodes 得到 node_id,需要在要成为的从节点的 Redis(7022)上执行。
- 192.168.100.134:7022> cluster nodes #查看节点信息
- 7438368ca8f8a27fdf2da52940bb50098a78c6fc 192.168.100.136:7022 master - 0 1488255023528 5 connected
- e1b78bb74970d0353832b2913e9b35eba74a2a1a 192.168.100.134:7022 myself,master - 0 0 0 connected
- 05e72d06edec6a920dd91b050c7a315937fddb66 192.168.100.136:7021 master - 0 1488255022526 2 connected 10923-16383
- b461a30fde28409c38ee6c32db1cd267a6cfd125 192.168.100.135:7021 master - 0 1488255026533 3 connected 5462-10922
- 11f9169577352c33d85ad0d1ca5f5bf0deba3209 192.168.100.134:7021 master - 0 1488255025531 1 connected 0-5461
- 2b8b518324de0990ca587b47f6316e5f07b1df59 192.168.100.135:7022 master - 0 1488255024530 4 connected
- #成为135:7021的从节点
- 192.168.100.134:7022> cluster replicate b461a30fde28409c38ee6c32db1cd267a6cfd125
- OK
处理其他 2 个节点:
- #成为136:7021的从节点
- 192.168.100.135:7022> cluster replicate 05e72d06edec6a920dd91b050c7a315937fddb66
- OK
- #成为134:7021的从节点
- 192.168.100.136:7022> cluster replicate 11f9169577352c33d85ad0d1ca5f5bf0deba3209
- OK
查看节点状态:cluster nodes
- 2b8b518324de0990ca587b47f6316e5f07b1df59 192.168.100.135:7022 slave 05e72d06edec6a920dd91b050c7a315937fddb66 0 1488255859347 4 connected
- 11f9169577352c33d85ad0d1ca5f5bf0deba3209 192.168.100.134:7021 myself,master - 0 0 1 connected 0-5461
- 05e72d06edec6a920dd91b050c7a315937fddb66 192.168.100.136:7021 master - 0 1488255860348 2 connected 10923-16383
- e1b78bb74970d0353832b2913e9b35eba74a2a1a 192.168.100.134:7022 slave b461a30fde28409c38ee6c32db1cd267a6cfd125 0 1488255858344 3 connected
- 7438368ca8f8a27fdf2da52940bb50098a78c6fc 192.168.100.136:7022 slave 11f9169577352c33d85ad0d1ca5f5bf0deba3209 0 1488255856341 5 connected
- b461a30fde28409c38ee6c32db1cd267a6cfd125 192.168.100.135:7021 master - 0 1488255857343 3 connected 5462-10922
可以通过查看 slave 对应的 node_id 找出它的 master 节点,如以上操作遇到问题可以查看 / var/log/redis / 目录下的日志。到此 Redis Cluster 分片、高可用部署完成,接着继续说明一下集群的相关管理命令。
上面已经介绍了一部分 Cluster 相关的命令,现在对所有的命令所以下说明。
- CLUSTER info:打印集群的信息。
- CLUSTER nodes:列出集群当前已知的所有节点(node)的相关信息。
- CLUSTER meet :将ip和port所指定的节点添加到集群当中。
- CLUSTER addslots [slot ...]:将一个或多个槽(slot)指派(assign)给当前节点。
- CLUSTER delslots [slot ...]:移除一个或多个槽对当前节点的指派。
- CLUSTER slots:列出槽位、节点信息。
- CLUSTER slaves :列出指定节点下面的从节点信息。
- CLUSTER replicate :将当前节点设置为指定节点的从节点。
- CLUSTER saveconfig:手动执行命令保存保存集群的配置文件,集群默认在配置修改的时候会自动保存配置文件。
- CLUSTER keyslot :列出key被放置在哪个槽上。
- CLUSTER flushslots:移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
- CLUSTER countkeysinslot :返回槽目前包含的键值对数量。
- CLUSTER getkeysinslot :返回count个槽中的键。
- CLUSTER setslot node 将槽指派给指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽,然后再进行指派。
- CLUSTER setslot migrating 将本节点的槽迁移到指定的节点中。
- CLUSTER setslot importing 从 node_id 指定的节点中导入槽 slot 到本节点。
- CLUSTER setslot stable 取消对槽 slot 的导入(import)或者迁移(migrate)。
- CLUSTER failover:手动进行故障转移。
- CLUSTER forget :从集群中移除指定的节点,这样就无法完成握手,过期时为60s,60s后两节点又会继续完成握手。
- CLUSTER reset [HARD|SOFT]:重置集群信息,soft是清空其他节点的信息,但不修改自己的id,hard还会修改自己的id,不传该参数则使用soft方式。
- CLUSTER count-failure-reports :列出某个节点的故障报告的长度。
- CLUSTER SET-CONFIG-EPOCH:设置节点epoch,只有在节点加入集群前才能设置。
为了更好的展示上面命令,先为这个新集群插入一些数据:通过脚本插入:
View Code
- #!/usr/bin/python
- # -*- encoding: utf-8 -*-
- import redis
- import time
- import random
- import sys
- from rediscluster import StrictRedisCluster
- redis_nodes = [{'host':'192.168.100.134','port':7021},
- {'host':'192.168.100.135','port':7021},
- {'host':'192.168.100.136','port':7021},
- {'host':'192.168.100.134','port':7022},
- {'host':'192.168.100.135','port':7022},
- {'host':'192.168.100.136','port':7022}
- ]
- try:
- r = StrictRedisCluster(startup_nodes=redis_nodes,password='dxy')
- except Exception,e:
- print "Connect Error!"
- sys.exit()
- #使得一个主从节点全部挂了,其他节点也支持数据处理
- r.config_set('cluster-require-full-coverage','yes')
- max_long = 9223372036854775807
- set_index = max_long
- post_index = max_long
- count = 0
- num_sets = 300000
- set_size = 1
- for i in xrange(0, num_sets):
- for j in xrange(0, set_size):
- r.zadd("%s" % (set_index), time.time() * (random.random() + 1),post_index)
- post_index = max_long - random.randint(1, 10000000000)
- set_index -= 1
这里说明一下上面没有介绍过的管理命令:
①:cluster slots 列出槽位和对应节点的信息
- 192.168.100.134:7021> cluster slots
- 1) 1) (integer) 0
- 2) (integer) 5461
- 3) 1) "192.168.100.134"
- 2) (integer) 7021
- 3) "11f9169577352c33d85ad0d1ca5f5bf0deba3209"
- 4) 1) "192.168.100.136"
- 2) (integer) 7022
- 3) "7438368ca8f8a27fdf2da52940bb50098a78c6fc"
- 2) 1) (integer) 10923
- 2) (integer) 16383
- 3) 1) "192.168.100.136"
- 2) (integer) 7021
- 3) "05e72d06edec6a920dd91b050c7a315937fddb66"
- 4) 1) "192.168.100.135"
- 2) (integer) 7022
- 3) "2b8b518324de0990ca587b47f6316e5f07b1df59"
- 3) 1) (integer) 5462
- 2) (integer) 10922
- 3) 1) "192.168.100.135"
- 2) (integer) 7021
- 3) "b461a30fde28409c38ee6c32db1cd267a6cfd125"
- 4) 1) "192.168.100.134"
- 2) (integer) 7022
- 3) "e1b78bb74970d0353832b2913e9b35eba74a2a1a"
②:cluster slaves:列出指定节点的从节点
- 192.168.100.134:7021> cluster slaves 11f9169577352c33d85ad0d1ca5f5bf0deba3209
- 1) "7438368ca8f8a27fdf2da52940bb50098a78c6fc 192.168.100.136:7022 slave 11f9169577352c33d85ad0d1ca5f5bf0deba3209 0 1488274385311 5 connected"
③:cluster keyslot:列出 key 放在那个槽上
- 192.168.100.134:7021> cluster keyslot 9223372036854742675
- (integer) 10310
④:cluster countkeysinslot:列出指定槽位的 key 数量
- 192.168.100.134:7021> cluster countkeysinslot 1
- (integer) 19
⑤:cluster getkeysinslot :列出指定槽位中的指定数量的 key
- 192.168.100.134:7021> cluster getkeysinslot 1 3
- 1) "9223372036854493093"
- 2) "9223372036854511387"
- 3) "9223372036854522344"
⑥:...:手动迁移 192.168.100.134:7021 的 0 槽位到 192.168.100.135:7021
- 1:首先查看各节点的槽位
- 192.168.100.134:7021> cluster nodes
- 2b8b518324de0990ca587b47f6316e5f07b1df59 192.168.100.135:7022 slave 05e72d06edec6a920dd91b050c7a315937fddb66 0 1488295105089 4 connected
- 11f9169577352c33d85ad0d1ca5f5bf0deba3209 192.168.100.134:7021 myself,master - 0 0 7 connected 0-5461
- 05e72d06edec6a920dd91b050c7a315937fddb66 192.168.100.136:7021 master - 0 1488295107092 2 connected 10923-16383
- e1b78bb74970d0353832b2913e9b35eba74a2a1a 192.168.100.134:7022 slave b461a30fde28409c38ee6c32db1cd267a6cfd125 0 1488295106090 6 connected
- 7438368ca8f8a27fdf2da52940bb50098a78c6fc 192.168.100.136:7022 slave 11f9169577352c33d85ad0d1ca5f5bf0deba3209 0 1488295104086 7 connected
- b461a30fde28409c38ee6c32db1cd267a6cfd125 192.168.100.135:7021 master - 0 1488295094073 6 connected 5462-10922
- 2:查看要迁移槽位的key
- 192.168.100.134:7021> cluster getkeysinslot 0 100
- 1) "9223372012094975807"
- 2) "9223372031034975807"
- 3:到目标节点执行导入操作
- 192.168.100.135:7021> cluster setslot 0 importing 11f9169577352c33d85ad0d1ca5f5bf0deba3209
- OK
- 192.168.100.135:7021> cluster nodes
- ...
- b461a30fde28409c38ee6c32db1cd267a6cfd125 192.168.100.135:7021 myself,master - 0 0 6 connected 5462-10922 [0-<-11f9169577352c33d85ad0d1ca5f5bf0deba3209]
- ...
- 4:到源节点进行迁移操作
- 192.168.100.134:7021> cluster setslot 0 migrating b461a30fde28409c38ee6c32db1cd267a6cfd125
- OK
- 192.168.100.134:7021> cluster nodes
- ...
- 11f9169577352c33d85ad0d1ca5f5bf0deba3209 192.168.100.134:7021 myself,master - 0 0 7 connected 0-5461 [0->-b461a30fde28409c38ee6c32db1cd267a6cfd125]
- ...
- 5:在源节点迁移槽位中的key到目标节点:MIGRATE host port key destination-db timeout [COPY] [REPLACE]
- 192.168.100.134:7021> 192.168.100.135 7021 9223372031034975807 0 5000 replace
- OK
- 192.168.100.134:7021> 192.168.100.135 7021 9223372012094975807 0 5000 replace
- OK
- 192.168.100.134:7021> cluster getkeysinslot 0 100 #key迁移完之后,才能进行下一步
- (empty list or set)
- 6:最后设置槽位到指定节点,命令将会广播给集群其他节点,已经将Slot转移到目标节点
- 192.168.100.135:7021> cluster setslot 0 node b461a30fde28409c38ee6c32db1cd267a6cfd125
- OK
- 192.168.100.134:7021> cluster setslot 0 node b461a30fde28409c38ee6c32db1cd267a6cfd125
- OK
- 7:验证是否迁移成功:
- 192.168.100.134:7021> cluster nodes
- ...
- 11f9169577352c33d85ad0d1ca5f5bf0deba3209 192.168.100.134:7021 myself,master - 0 0 9 connected 1-5461 #变了
- ...
- b461a30fde28409c38ee6c32db1cd267a6cfd125 192.168.100.135:7021 master - 0 1488300965322 10 connected 0 5462-10922
- 查看槽位信息:
- 192.168.100.134:7021> cluster slots
- 1) 1) (integer) 10923
- 2) (integer) 16383
- 3) 1) "192.168.100.136"
- 2) (integer) 7021
- 3) "05e72d06edec6a920dd91b050c7a315937fddb66"
- 2) 1) (integer) 1
- 2) (integer) 5461
- 3) 1) "192.168.100.134"
- 2) (integer) 7021
- 3) "11f9169577352c33d85ad0d1ca5f5bf0deba3209"
- 3) 1) (integer) 0
- 2) (integer) 0
- 3) 1) "192.168.100.135"
- 2) (integer) 7021
- 3) "b461a30fde28409c38ee6c32db1cd267a6cfd125"
- 4) 1) (integer) 5462
- 2) (integer) 10922
- 3) 1) "192.168.100.135"
- 2) (integer) 7021
- 3) "b461a30fde28409c38ee6c32db1cd267a6cfd125"
- 查看数据是否迁移成功:
- 192.168.100.134:7021> cluster getkeysinslot 0 100
- (empty list or set)
- 192.168.100.135:7021> cluster getkeysinslot 0 100
- 1) "9223372012094975807"
- 2) "9223372031034975807"
对于大量 slot 要迁移,而且 slot 里也有大量的 key 的话,可以按照上面的步骤写个脚本处理,或则用后面脚本部署里介绍的处理。
大致的迁移 slot 的步骤如下:
- 1,在目标节点上声明将从源节点上迁入Slot CLUSTER SETSLOT IMPORTING
- 2,在源节点上声明将往目标节点迁出Slot CLUSTER SETSLOT migrating
- 3,批量从源节点获取KEY CLUSTER GETKEYSINSLOT
- 4,将获取的Key迁移到目标节点 MIGRATE 0
- 重复步骤3,4直到所有数据迁移完毕,MIGRATE命令会将所有的指定的key通过RESTORE key ttl serialized-value REPLACE迁移给target
- 5,分别向双方节点发送 CLUSTER SETSLOT NODE ,该命令将会广播给集群其他节点,取消importing和migrating。
- 6,等待集群状态变为OK CLUSTER INFO 中的 cluster_state = ok
注意:这里在操作的时候,若各节点有认证,执行的时候会出现:
(error) ERR Target instance replied with error: NOAUTH Authentication required.
若确定执行的迁移,本文中是把所有节点的 masterauth 和 requirepass 注释掉之后进行的,等进行完之后再开启认证。
⑦:cluster forget:从集群中移除指定的节点,这样就无法完成握手,过期时为 60s,60s 后两节点又会继续完成握手。
- 192.168.100.134:7021> cluster nodes
- 05e72d06edec6a920dd91b050c7a315937fddb66 192.168.100.136:7021 master - 0 1488302330582 2 connected 10923-16383
- 11f9169577352c33d85ad0d1ca5f5bf0deba3209 192.168.100.134:7021 myself,master - 0 0 9 connected 1-5461
- b461a30fde28409c38ee6c32db1cd267a6cfd125 192.168.100.135:7021 master - 0 1488302328576 10 connected 0 5462-10922
- ...
- 192.168.100.134:7021> cluster forget 05e72d06edec6a920dd91b050c7a315937fddb66
- OK
- 192.168.100.134:7021> cluster nodes
- 11f9169577352c33d85ad0d1ca5f5bf0deba3209 192.168.100.134:7021 myself,master - 0 0 9 connected 1-5461
- b461a30fde28409c38ee6c32db1cd267a6cfd125 192.168.100.135:7021 master - 0 1488302376718 10 connected 0 5462-10922
- ...
- 一分钟之后:
- 192.168.100.134:7021> cluster nodes
- 05e72d06edec6a920dd91b050c7a315937fddb66 192.168.100.136:7021 master - 0 1488302490107 2 connected 10923-16383
- 11f9169577352c33d85ad0d1ca5f5bf0deba3209 192.168.100.134:7021 myself,master - 0 0 9 connected 1-5461
- b461a30fde28409c38ee6c32db1cd267a6cfd125 192.168.100.135:7021 master - 0 1488302492115 10 connected 0 5462-10922
⑧:cluster failover:手动进行故障转移,在下一节会详解。需要注意的是在需要故障转移的节点上执行,必须在 slave 节点上执行,否则报错:
(error) ERR You should send CLUSTER FAILOVER to a slave
⑨:cluster flushslots:需要在没有 key 的节点执行,移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点,该节点所有数据丢失。
- 192.168.100.136:7022> cluster nodes
- 05e72d06edec6a920dd91b050c7a315937fddb66 192.168.100.136:7021 master - 0 1488255398859 2 connected 10923-16383
- ...
- 192.168.100.136:7021> cluster flushslots
- OK
- 192.168.100.136:7021> cluster nodes
- 05e72d06edec6a920dd91b050c7a315937fddb66 192.168.100.136:7021 myself,master - 0 0 2 connected
- ...
⑩:cluster reset: 需要在没有 key 的节点执行,重置集群信息。
- 192.168.100.134:7021> cluster reset
- OK
- 192.168.100.134:7021> cluster nodes
- 11f9169577352c33d85ad0d1ca5f5bf0deba3209 192.168.100.134:7021 myself,master - 0 0 9 connected
Redis Cluster 有一套管理脚本,如:创建集群、迁移节点、增删槽位等,这些脚本都存放在源码包里,都是用 ruby 编写的。现在测试用下脚本完成集群的部署。
①:按照需求创建 Redis 实例,6 个实例(3 主 3 从)。
②:安全需要 ruby 模块:
- apt-get install ruby
- gem install redis
③:脚本 redis-trib.rb(/usr/local/src/redis-3.2.8/src)
- ./redis-trib.rb help
- Usage: redis-trib
- #创建集群
- create host1:port1 ... hostN:portN
- --replicas #带上该参数表示是否有从,arg表示从的数量
- #检查集群
- check host:port
- #查看集群信息
- info host:port
- #修复集群
- fix host:port
- --timeout
- #在线迁移slot
- reshard host:port #个是必传参数,用来从一个节点获取整个集群信息,相当于获取集群信息的入口
- --from #需要从哪些源节点上迁移slot,可从多个源节点完成迁移,以逗号隔开,传递的是节点的node id,还可以直接传递--from all,这样源节点就是集群的所有节点,不传递该参数的话,则会在迁移过程中提示用户输入
- --to #slot需要迁移的目的节点的node id,目的节点只能填写一个,不传递该参数的话,则会在迁移过程中提示用户输入。
- --slots #需要迁移的slot数量,不传递该参数的话,则会在迁移过程中提示用户输入。
- --yes #设置该参数,可以在打印执行reshard计划的时候,提示用户输入yes确认后再执行reshard
- --timeout #设置migrate命令的超时时间。
- --pipeline #定义cluster getkeysinslot命令一次取出的key数量,不传的话使用默认值为10。
- #平衡集群节点slot数量
- rebalance host:port
- --weight
- --auto-weights
- --use-empty-masters
- --timeout
- --simulate
- --pipeline
- --threshold
- #将新节点加入集群
- add-node new_host:new_port existing_host:existing_port
- --slave
- --master-id
- #从集群中删除节点
- del-node host:port node_id
- #设置集群节点间心跳连接的超时时间
- set-timeout host:port milliseconds
- #在集群全部节点上执行命令
- call host:port command arg arg .. arg
- #将外部redis数据导入集群
- import host:port
- --from
- --copy
- --replace
- #帮助
- help (show this help)
- For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
1)创建集群 cretate:6 个节点,每个节点一个从库,这里有个问题是不能指定那个从库属于哪个主库,不过可以先添加 3 个主库,通过新增节点(add-node)来添加从库到指定主库。
- ./redis-trib.rb create --replicas 1 192.168.100.134:7021 192.168.100.135:7021 192.168.100.136:7021 192.168.100.134:7022 192.168.100.135:7022 192.168.100.136:7022
View Code
- >>> Creating cluster
- >>> Performing hash slots allocation on 6 nodes...
- Using 3 masters:
- 192.168.100.134:7021
- 192.168.100.135:7021
- 192.168.100.136:7021
- Adding replica 192.168.100.135:7022 to 192.168.100.134:7021
- Adding replica 192.168.100.134:7022 to 192.168.100.135:7021
- Adding replica 192.168.100.136:7022 to 192.168.100.136:7021
- M: 7fa64d250b595d8ac21a42477af5ac8c07c35d83 192.168.100.134:7021
- slots:0-5460 (5461 slots) master
- M: 51bf103f7cf6b5ede6e009ce489fdeec14961be8 192.168.100.135:7021
- slots:5461-10922 (5462 slots) master
- M: 0191a8b52646fb5c45323ab0c1a1a79dc8f3aea2 192.168.100.136:7021
- slots:10923-16383 (5461 slots) master
- S: 5476787f31fa375fda6bb32676a969c8b8adfbc2 192.168.100.134:7022
- replicates 51bf103f7cf6b5ede6e009ce489fdeec14961be8
- S: 77d02fef656265c9c421fef425527c510e4cfcb8 192.168.100.135:7022
- replicates 7fa64d250b595d8ac21a42477af5ac8c07c35d83
- S: 140c72a443eb1c7b87b9cdd06b7f71cd583b2e1d 192.168.100.136:7022
- replicates 0191a8b52646fb5c45323ab0c1a1a79dc8f3aea2
- Can I set the above configuration? (type 'yes' to accept): yes
- >>> Nodes configuration updated
- >>> Assign a different config epoch to each node
- >>> Sending CLUSTER MEET messages to join the cluster
- Waiting for the cluster to join..
- >>> Performing Cluster Check (using node 192.168.100.134:7021)
- M: 7fa64d250b595d8ac21a42477af5ac8c07c35d83 192.168.100.134:7021
- slots:0-5460 (5461 slots) master
- 1 additional replica(s)
- S: 77d02fef656265c9c421fef425527c510e4cfcb8 192.168.100.135:7022
- slots: (0 slots) slave
- replicates 7fa64d250b595d8ac21a42477af5ac8c07c35d83
- S: 5476787f31fa375fda6bb32676a969c8b8adfbc2 192.168.100.134:7022
- slots: (0 slots) slave
- replicates 51bf103f7cf6b5ede6e009ce489fdeec14961be8
- M: 51bf103f7cf6b5ede6e009ce489fdeec14961be8 192.168.100.135:7021
- slots:5461-10922 (5462 slots) master
- 1 additional replica(s)
- M: 0191a8b52646fb5c45323ab0c1a1a79dc8f3aea2 192.168.100.136:7021
- slots:10923-16383 (5461 slots) master
- 1 additional replica(s)
- S: 140c72a443eb1c7b87b9cdd06b7f71cd583b2e1d 192.168.100.136:7022
- slots: (0 slots) slave
- replicates 0191a8b52646fb5c45323ab0c1a1a79dc8f3aea2
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
2)测试集群 check ip:port:测试集群是否分配完了 slot
- ./redis-trib.rb check 192.168.100.134:7021
View Code
- >>> Performing Cluster Check (using node 192.168.100.134:7021)
- M: 7fa64d250b595d8ac21a42477af5ac8c07c35d83 192.168.100.134:7021
- slots:0-5460 (5461 slots) master
- 1 additional replica(s)
- S: 77d02fef656265c9c421fef425527c510e4cfcb8 192.168.100.135:7022
- slots: (0 slots) slave
- replicates 7fa64d250b595d8ac21a42477af5ac8c07c35d83
- S: 5476787f31fa375fda6bb32676a969c8b8adfbc2 192.168.100.134:7022
- slots: (0 slots) slave
- replicates 51bf103f7cf6b5ede6e009ce489fdeec14961be8
- M: 51bf103f7cf6b5ede6e009ce489fdeec14961be8 192.168.100.135:7021
- slots:5461-10922 (5462 slots) master
- 1 additional replica(s)
- M: 0191a8b52646fb5c45323ab0c1a1a79dc8f3aea2 192.168.100.136:7021
- slots:10923-16383 (5461 slots) master
- 1 additional replica(s)
- S: 140c72a443eb1c7b87b9cdd06b7f71cd583b2e1d 192.168.100.136:7022
- slots: (0 slots) slave
- replicates 0191a8b52646fb5c45323ab0c1a1a79dc8f3aea2
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
3)查看集群信息 info ip:port:查看集群信息:包括 slot、slave、和 key 的数量分布
- ./redis-trib.rb info 192.168.100.134:7021
View Code
- 192.168.100.134:7021 (7fa64d25...) -> 58086 keys | 5461 slots | 1 slaves.
- 192.168.100.135:7021 (51bf103f...) -> 58148 keys | 5462 slots | 1 slaves.
- 192.168.100.136:7021 (0191a8b5...) -> 58051 keys | 5461 slots | 1 slaves.
- [OK] 174285 keys in 3 masters.
- 10.64 keys per slot on average.
4)平衡节点的 slot 数量 rebalance ip:port:平均各个节点的 slot 数量
- ./redis-trib.rb rebalance 192.168.100.134:7021
流程:
View Code
- 1、load_cluster_info_from_node方法先加载集群信息。
- 2、计算每个master的权重,根据参数--weight ,为每个设置的节点分配权重,没有设置的节点,则权重默认为1。
- 3、根据每个master的权重,以及总的权重,计算自己期望被分配多少个slot。计算的方式为:总slot数量 * (自己的权重 / 总权重)。
- 4、计算每个master期望分配的slot是否超过设置的阈值,即--threshold 设置的阈值或者默认的阈值。计算的方式为:先计算期望移动节点的阈值,算法为:(100-(100.0*expected/n.slots.length)).abs,如果计算出的阈值没有超出设置阈值,则不需要为该节点移动slot。只要有一个master的移动节点超过阈值,就会触发rebalance操作。
- 5、如果触发了rebalance操作。那么就开始执行rebalance操作,先将每个节点当前分配的slots数量减去期望分配的slot数量获得balance值。将每个节点的balance从小到大进行排序获得sn数组。
- 6、用dst_idx和src_idx游标分别从sn数组的头部和尾部开始遍历。目的是为了把尾部节点的slot分配给头部节点。sn数组保存的balance列表排序后,负数在前面,正数在后面。负数表示需要有slot迁入,所以使用dst_idx游标,正数表示需要有slot迁出,所以使用src_idx游标。理论上sn数组各节点的balance值加起来应该为0,不过由于在计算期望分配的slot的时候只是使用直接取整的方式,所以可能出现balance值之和不为0的情况,balance值之和不为0即为节点不平衡的slot数量,由于slot总数有16384个,不平衡数量相对于总数,基数很小,所以对rebalance流程影响不大。
5)删除集群节点 del-node ip:port <node_id>:只能删除没有分配 slot 的节点,从集群中删出之后直接关闭实例
- ./redis-trib.rb del-node 192.168.100.135:7022 77d02fef656265c9c421fef425527c510e4cfcb8
View Code
- #删除成功
- >>> Removing node 77d02fef656265c9c421fef425527c510e4cfcb8 from cluster 192.168.100.135:7022
- >>> Sending CLUSTER FORGET messages to the cluster...
- >>> SHUTDOWN the node.
- #删除失败
- >>> Removing node 51bf103f7cf6b5ede6e009ce489fdeec14961be8 from cluster 192.168.100.135:7021
- [ERR] Node 192.168.100.135:7021 is not empty! Reshard data away and try again.
流程:
View Code
- 1、通过load_cluster_info_from_node方法转载集群信息。
- 2、根据传入的node id获取节点,如果节点没找到,则直接提示错误并退出。
- 3、如果节点分配的slot不为空,则直接提示错误并退出。
- 4、遍历集群内的其他节点,执行cluster forget命令,从每个节点中去除该节点。如果删除的节点是master,而且它有slave的话,这些slave会去复制其他master,调用的方法是get_master_with_least_replicas,与add-node没设置--master-id寻找master的方法一样。
- 5、然后关闭该节点
6)添加集群节点 add-node :新节点加入集群,节点可以为 master,也可以为某个 master 节点的 slave。
添加一个主节点:134:7022 加入到 134:7021 的集群当中
- ./redis-trib.rb add-node 192.168.100.134:7022 192.168.100.134:7021
View Code
- >>> Adding node 192.168.100.134:7022 to cluster 192.168.100.134:7021
- >>> Performing Cluster Check (using node 192.168.100.134:7021)
- M: 7fa64d250b595d8ac21a42477af5ac8c07c35d83 192.168.100.134:7021
- slots:0-5460 (5461 slots) master
- 0 additional replica(s)
- M: 51bf103f7cf6b5ede6e009ce489fdeec14961be8 192.168.100.135:7021
- slots:5461-10922 (5462 slots) master
- 0 additional replica(s)
- M: 0191a8b52646fb5c45323ab0c1a1a79dc8f3aea2 192.168.100.136:7021
- slots:10923-16383 (5461 slots) master
- 0 additional replica(s)
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
- >>> Send CLUSTER MEET to node 192.168.100.134:7022 to make it join the cluster.
- [OK] New node added correctly.
添加一个从节点:135:7022 加入到 134:7021 的集群当中,并且作为指定 <node_id> 的从库
- ./redis-trib.rb add-node --slave --master-id 7fa64d250b595d8ac21a42477af5ac8c07c35d83 192.168.100.135:7022 192.168.100.134:7021
- >>> Adding node 192.168.100.135:7022 to cluster 192.168.100.134:7021
- >>> Performing Cluster Check (using node 192.168.100.134:7021)
- M: 7fa64d250b595d8ac21a42477af5ac8c07c35d83 192.168.100.134:7021
- slots:0-5460 (5461 slots) master
- 0 additional replica(s)
- M: 5476787f31fa375fda6bb32676a969c8b8adfbc2 192.168.100.134:7022
- slots: (0 slots) master
- 0 additional replica(s)
- M: 51bf103f7cf6b5ede6e009ce489fdeec14961be8 192.168.100.135:7021
- slots:5461-10922 (5462 slots) master
- 0 additional replica(s)
- M: 0191a8b52646fb5c45323ab0c1a1a79dc8f3aea2 192.168.100.136:7021
- slots:10923-16383 (5461 slots) master
- 0 additional replica(s)
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
- >>> Send CLUSTER MEET to node 192.168.100.135:7022 to make it join the cluster.
- Waiting for the cluster to join.
- >>> Configure
来源: http://www.cnblogs.com/zhoujinyi/p/6477133.html