转载于:http://shift-alt-ctrl.iteye.com/blog/2284890
Redis Cluster提供了在多个redis实例间数据自动分片(sharded)的特性,同时在partitions之间提供了一定程度的可用性保障,比如一些nodes失效时集群仍可以继续读写操作;不过当集群中较大规模的节点失效会导致集群停止服务,比如多数master失效(majority of masters)。在实用性方面,Redis Cluster能够做到:
1)在多个nodes间自动切分数据的能力(split)
2)当部分nodes失效时(或者nodes无法与其他nodes通信时),集群仍然可以继续操作
此外,我们已知Redis Sentinal模块已经支持在Master-Slave架构下自动Failover,当集群规模增大、数据需要sharding时,我们需要采用Cluster架构。
Redis Cluster在3.0+版本才正式发布,宣称可以支持1000个节点;当然在通常情况下,我们的集群可能在10~20个节点左右,毕竟节点越多其复杂度越大,维护成本越高。Redis Cluster中涉及到节点自动发现、failover、slave自动迁移等机制,基于gossip协议和普通的选举算法,并没有使用额外的服务协调组件,不过Cluster中所有的节点都需要彼此建立连接(full mesh)。
对于客户端应用而言,只需要声明集群的部分节点即可,客户端即可与其中一个节点建立连接,即可通过指令获取集群的所有状态信息,所以客户端实现也是非常轻量级的;此后客户端将会缓存集群的信息,这些信息包括nodes与slots的映射关系,那么当客户端需要提交请求时,它能够在客户端(单边)计算此操作应该转发给哪个节点,此后直接与相应的node建立连接并提交请求。所以Redis Cluster机制中,并不存在Proxy层。
一、集群TCP端口
每个redis实例都需要2个TCP端口,其一为服务于客户端的port,通常为6379;另外一个为“Redis Cluster bus”端口,此值为客户端port + 10000,假如客户端port为6379,那么bus端口即为16379,此端口我们无法通过配置来设定。(因为server的最大端口号为65535,所以客户端port不要设置的太大)
“Cluster bus”端口,用于nodes间通讯,比如“节点失效检测(failure detection)”、配置信息更新(备注:cluster内部的配置信息交换)、failover授权等等。bus端口上采用了封闭的二进制协议,通常客户端无法与bus口交互,同时为了安全起见,我们需要使用防火墙机制,让此端口只对nodes集群有效。
二、集群与Docker
当前Cluster尚不支持NATted环境,在一般环境中IP地址或者port会重新映射(remapped)。Docker使用了一种称为“port mapping”技术:在Docker容器内运行的程序使用的端口,将以另一个端口的方式暴露出去(Docket的宿主环境)。这可以允许一个Server(物理环境)上允许多个Docker容器,而且每个容器内的程序可以使用相同的端口。为了让Redis Cluster与Docker机制兼容,Docker需要使用“host networking mode”,具体信息请参考Dorcker文档。
三、集群数据分片机制
Redis Cluster并没有使用一致性hash机制,但是使用了一种不同的sharding方式:hash slot(哈希槽);Cluster将会分配16384个slot(此值不可修改),对于指定的key,将会对key使用CRC16算法计算出long数值,然后对16384取模,即可得出此key所属的slot。那么集群中每个node都负责一部分slots,比如集群由A、B、C三个节点构成(3个masters):
1)A中的slots区间为:0~5500
2)B中的slots区间为:5501~11000
3)C中的slots区间为:11001~16383
hash slot机制很像存储层面的block,所以在集群中新增、移除nodes将变得简单。比如,我想添加一个新的node D,我只需要将A、B、C中的部分slots迁移到D上即可(而不是对集群中所有的数据重新resharding);同理,如果想移除节点A,只需要将A上的slots迁移到其他节点,此后即可将A从集群中移除。(言外之意,不需要resharding,而且对客户端透明)
由此可见,hash slots从一个node迁移到另一个node,或者增删节点,都不需要中断用户操作,集群仍可以正常服务。
我们知道Redis支持“multiple key”操作(即多个key的数据在一次调用中返回),那么Cluster也支持此特性,但是要求所有的keys需要在一个hash slot上(即在同一个node上),为了确保多个keys所属与同一个slot,则要求使用“hash tags”。
“hash tags”:Redis Cluster支持的特性,在key字符串中如果包含"{}",那么“{}”之间的字符串即为“hash tags”,客户端(包括Server端)将根据“hash tags”来计算此key所属的slots,而不是key完整的字符串,当然存储仍使用key。所以,有了“hash tags”,我们可以强制某些keys被保存在相同的slots:比如,“foo”和“{foo}.another”将会保存同一个slot上。这对“multiple key”操作非常有帮助。
四、集群节点的主备模式
当部分masters节点失效或者无法与大多数节点通讯时,为了能够保持集群的有效性,Redis Cluster通常使用Master-Slave模式,即一个Master节点通常需要一个或者多个slaves,通过replicas方式来提高可用性。
比如上例中的三个节点,如果B失效,那么集群将无法继续提供服务,因为“5501~11000”区间的slots完全“丢失”了。为了避免这种情况,我们通常需要为每个Master增加至少一个slave。比如A1、B1、C1分别为A、B、C的slave节点,那么当B失效时,B1可以被提升为master,接管B的服务,从而集群仍然可以继续操作。(不过,此后如果B1也失效,集群将不可用)
从集群的整体架构拓扑可知,Cluster并没有统一的Primary节点,也不存在所谓的集群单点问题。
五、数据一致性
Redis Cluster不能保证“强一致性”(strong consistency),即在实际使用中,某些情况下已经writes成功的数据(已经向客户端确认成功的)可能会丢失。
第一个原因就是Master与slaves之间采用异步复制的方式,这意味着那些在master上写入成功但尚未replicas到slave时,如果master失效,也意味着这些writes数据丢失了。
1)Client向A提交write操作
2)A写入成功且向Client返回“OK”。(此时客户端逻辑则认为write操作成功)
3)A将操作通过异步的方式replication到slave A1上。
上述过程中可见,A不会等到slave A1复制成功后才向Client返回确认消息;所以在2)过程之后如果A失效了,A1将会被提升为Master,那么A1上尚未复制的writes操作意味着丢失了。。。
Redis Cluster支持“同步复制”,即使用“WAIT”指令(即在write操作之后紧跟一个WAIT指令,表示此客户端等待,直到Master将write被同步给slave之后才返回确认消息),它可以降低数据丢失的可能性,但这仍然不是严格意义上的“强一致性”(通常是二阶段提交)。
还有另一种情况会导致writes丢失:网络分区,network partition。比如有6个节点A、B、C,以及其对应的slaves A1、B1、C1,以及Client端为Z1;此时网络分区导致“A,C,A1,B1,C1”、“B、Z1”,其中Z1与“B”在一个分区,且与第一个分区完全隔离,即客户端被隔离在一个小分区中。因为Z1认为B是Master,所以它将继续writes;集群中故障检测、判定以及failover都需要一定的时间量,在此时间内,Z1仍将writes操作发送给B,但是failover结束后,B1被提升为Master(B也在隔离指定时间后,切换为read only状态),但是因为网络分区导致B无法将数据同步给B1,所以在failover期间发生的writes将丢失。
这里引入一个“node timeout”配置参数,当node将链接中断超过timeout后,master将被认为失效,此后将有其中一个slave来替代。当然,如果在timeout超时后,没有master接管,那么整个集群将处于error状态,中断所有的write请求。
六、集群配置参数
我们稍后会尝试搭建一个Cluster环境,在此之前先了解一下Cluster的几个配置参数,它们需要在redis.conf中声明:
1)cluster-enabled <yes/no>:首要参数,表示此redis实例是否支持cluster,“yes”表示开启,此后此redis实例可以被添加到集群中,“no”表示此redis为单实例运行。
2)cluster-config-file <filename>:cluster配置文件的名称,当集群信息发生变更时,node将会自动把这些信息持久化到此配置文件中,以便在启动时重新读取它。对于用户而言,通常不应该认为修改此文件内容。文件中会包含:集群中其他nodes信息、以及他们的状态,还有一些持久性的变量等。
3)cluster-node-timeout <毫秒数>:node在被认为失效之前,允许不可用的最长时间。如果Master处于“不可达”的时间超过此值,将会被failover。当然,每个node在此时间内不能与“多数派”nodes通讯,它也将终止接收writes请求,切换到read only模式。这个参数很重要,选择合适的值,对集群的有效性、数据一致性有极大影响。
4)cluster-slave-validity-factor <factor>:用于限定slave于master的失联时长的倍数;如果设置为0,slave总是尝试failover,不管master与slave之间的链接断开多久(即只要slave无法与master通讯,都会尝试进行failover;Cluster有选举机制,有可能会被否决);如果此值为正值,则失联的最大时长为:factor * node timeout,当失联时长超过此值后,slave触发failover。比如node timeout为5秒,factor为10,那么当slave与master失联超过50秒时,slave将会尽力尝试failover。此值需要合理设置,也会对集群有效性、数据一致性产生影响。
5)cluster-migration-barrier <count>:适用于“migration”架构场景(稍后介绍);master需要保留的slaves的最少个数;如果一个master拥有比此值更多的slaves,那么Cluster将会使用“migration”机制,将多余的slaves迁移到其他master上,这些master持有的slaves的数量低于此值。最终Cluster希望做到,slaves能够按需迁移,在failover期间,确保每个master都有一定量的slaves,以提高集群整体的可用性。(比如A有三个slaves:A1、A2、A3,而B只有一个slave B1,当B失效后,B1提升为master,但是B1没有任何slave,所以存在风险,那么migration机制,可以将A下的某个slave迁移到B1下,成为B1的slave。)
6)cluster-require-full-coverage <yes/no>:“集群是否需要全量覆盖”,如果设置为yes(默认值),当集群中有slots没有被任何node覆盖(通常是由于某个master失效,但是它也没有slave接管时),集群将会终止接收writes请求;如果设置为no,集群中那些服务正常的nodes(slots)仍然可以继续服务。
七、创建和使用集群
创建集群之前,需要准备一些空的redis实例,且它们支持集群模式,接下来我们在单机模拟一个Cluster测试环境,6个节点分别为三个masters和三个slaves,客户端port依次为:7000、7001、7002、7003、7004、7005,每个节点使用单独的redis.conf文件,它们使用不同的datadir,以避免存储时冲突。
- redis-7000.conf
- redis-7001.conf
- redis-7002.conf
- redis-7003.conf
- redis-7004.conf
- redis-7005.conf
- ##在redis的根目录创建上述配置文件
- ##适当修改每个文件中的数据目录和端口即可
- ##redis需要首先执行make
redis-7000.conf配置样例:
- daemonize yes
- pidfile /var/run/redis-7000.pid
- port 7000
- bind 127.0.0.1
- dir /data/redis/7000
- cluster-enabled yes
- ##默认保存在dir下
- cluster-config-file nodes.conf
- cluster-node-timeout 5000
- appendonly yes
nodes.conf这个文件,用于保存Cluster信息的,通常不要人为的去修改它,以免带来错误;支持集群模式的redis实例,在启动时会初始化nodes.conf信息,同时当它加入集群后,如果收到集群信息的变更时,将会修改此文件内容。因为masters需要“多数派”,所以最小Cluster的构建规模,至少包含3个master节点,本文为了展示Cluster的最小完整拓扑结构,还为每个master增加了一个slave。
我们依次启动上述redis实例!在启动日志中,我们可以看到每个redis实例都会创建一个node ID的字符串,当然此信息也可以在各自的nodes.conf中查看。集群中,所有的node都会持有唯一的ID,Cluster并没有使用IP + Port方式来标记一个实例,因为IP +Port可能会随时改变,这会影响集群中节点的判断,所以它使用了node ID,任何节点的ID一旦生成将会写入到nodes.conf中,且此后不会被修改。
此后我们需要将这些孤立的redis node构建成Cluster环境,我们可以使用Redis提供了帮助脚本redis-trib来完成,这个脚本使用ruby开发,所以我们需要安装ruby相关依赖:
- #任意目录
- > gem install redis
因为国内网络问题可能导致无法安装,错误提示如下:
- ERROR: Could not find a valid gem 'redis' (>= 0), here is why:
- Unable to download data from https://rubygems.org/ - Errno::ECONNRESET: Connection reset by peer - SSL_connect (https://rubygems.org/latest_specs.4.8.gz)
建议先增加一个国内的ruby镜像地址,然后再执行gem指令:
- > gem sources -a https://ruby.taobao.org/
安装成后,我们即可以使用redis-trib构建集群了:
- > cd src
- > ./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
redis-trib脚本位于src下,“create”指令就是用来构建集群,“replicas 1”表示每个master只有一个slave,将会根据此规则解析此后的IP:Port地址列表,6个地址,前三个是master,后三个是slave:
- Using 3 masters:
- 127.0.0.1:7000
- 127.0.0.1:7001
- 127.0.0.1:7002
- Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
- Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
- Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
- M: 545d7cfe420163529962911fe244d356140e3756 127.0.0.1:7000
- slots:0-5460 (5461 slots) master
- M: e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8 127.0.0.1:7001
- slots:5461-10922 (5462 slots) master
- M: db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3 127.0.0.1:7002
- slots:10923-16383 (5461 slots) master
- S: 48abc812431cf7b1e20830bcb73fa2e15169a970 127.0.0.1:7003
- replicates 545d7cfe420163529962911fe244d356140e3756
- S: a6c9e20808c34ffac40e3fb2d0938b52359ec54f 127.0.0.1:7004
- replicates e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8
- S: a91205008a4f0b5a1c0aff5d08f9d903f1d72182 127.0.0.1:7005
- replicates db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3
- 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 127.0.0.1:7000)
- M: 545d7cfe420163529962911fe244d356140e3756 127.0.0.1:7000
- slots:0-5460 (5461 slots) master
- M: e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8 127.0.0.1:7001
- slots:5461-10922 (5462 slots) master
- M: db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3 127.0.0.1:7002
- slots:10923-16383 (5461 slots) master
- M: 48abc812431cf7b1e20830bcb73fa2e15169a970 127.0.0.1:7003
- slots: (0 slots) master
- replicates 545d7cfe420163529962911fe244d356140e3756
- M: a6c9e20808c34ffac40e3fb2d0938b52359ec54f 127.0.0.1:7004
- slots: (0 slots) master
- replicates e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8
- M: a91205008a4f0b5a1c0aff5d08f9d903f1d72182 127.0.0.1:7005
- slots: (0 slots) master
- replicates db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
非常简单,到此为止简单的集群已经构建完成,16384个slots也全部分配。接下来我们使用jedis客户端对集群数据进行几次操作:
- <dependency>
- <groupId>redis.clients</groupId>
- <artifactId>jedis</artifactId>
- <version>2.8.1</version>
- </dependency>
- Set<HostAndPort> hosts = new HashSet<>();
- //添加任意多个redis实例的地址
- //不需要将集群中所有的地址都穷举
- hosts.add(new HostAndPort("127.0.0.1",7000));
- hosts.add(new HostAndPort("127.0.0.1",7001));
- hosts.add(new HostAndPort("127.0.0.1",7002));
- JedisPoolConfig poolConfig = new JedisPoolConfig();
- poolConfig.setBlockWhenExhausted(true);
- poolConfig.setMaxTotal(32);
- poolConfig.setMaxIdle(2);
- JedisCluster jedisCluster = new JedisCluster(hosts,poolConfig);
- jedisCluster.set("test001","test001");
- System.out.println(jedisCluster.get("test001"));
- jedisCluster.close();
我们也可以通过redis-cli中断来操作集群数据,比如:
- #任何一个节点均可
- #必须需要使用-c参数,表示开启集群模式,
- #可以提示“ASK”、“MOVED”等slots转移信息
- > ./redis-cli -c -p 7000
- 127.0.0.1:7000> set test002 test002
- -> Redirected to slot [13391] located at 127.0.0.1:7002
- OK
- -> set test002 test002
- OK
redis-cli和我们的Jedis客户端在功能上并没有太大区别,在集群模式下,向节点写入key时,当前node将会告知client将key转发到合适的node上,比如我们在7000这个实例上写入“test002”(首次写入,Client此时还没有nodes与slots的映射关系),此时返回“Redirected”信息,告知Client此key应该被写入在7002节点,那么Client将会在7002节点上重试,写入成功并返回“OK”。每当Client收到“Redirected”反馈信息时,它都会重新获取集群中nodes与slots的映射关系(任何node都可以交付映射信息),并在本地缓存,此后再次写入时,Client将直接与相应的node交互即可,比如第二次写入“test002”时,直接返回了“OK”。
Resharding
Resharding就是将数据重新分片,意味着我们可以将nodes上的部分slots迁移到其他nodes上,redis-trib辅助工具仍然可以帮助我们:
- ##注意,7000只是trib登陆的实例
- > ./redis-trib.rb reshard 127.0.0.1:7000
- ....
- How many slots do you want to move (from 1 to 16384)? 1000
- What is the receiving node 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:545d7cfe420163529962911fe244d356140e3756
- Source node #2:done
在slots重新分配的过程中,
1)需要输入允许迁移的slots数量,最终将有指定数量的slots被迁移到目标node上。
2)需要输入“Receiving”端的node ID,表示集群中哪个node接收slots,通常是新的node或者负载较小的node。
3)需要输入“Source”端的node ID,表示“指定数量的slots”将从哪些nodes上迁出;允许依次输入多个ID,输入“all”表示从所有nodes上(不包括Receiving端),“done”表示输入结束,开始执行reshard。
之所以“reshard”,原因就是Redis Cluster目前还没有提供“rebalance”机制,它不能自动平衡集群中每个节点上的slots分布,不过此特性将来会添加进去。
自动Failover
我们可以通过“cluster nodes”指令来查看集群中节点的状态和拓扑关系:
- #登陆到任意节点
- > ./redis-cli -c -p 7000
- 127.0.0.1:7000> cluster nodes
- db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3 127.0.0.1:7002 master - 0 1458555571985 3 connected 10923-16383
- a91205008a4f0b5a1c0aff5d08f9d903f1d72182 127.0.0.1:7005 slave db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3 0 1458555572489 6 connected
- 545d7cfe420163529962911fe244d356140e3756 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
- e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8 127.0.0.1:7001 master - 0 1458555571480 2 connected 5461-10922
- 48abc812431cf7b1e20830bcb73fa2e15169a970 127.0.0.1:7003 slave 545d7cfe420163529962911fe244d356140e3756 0 1458555571480 4 connected
- a6c9e20808c34ffac40e3fb2d0938b52359ec54f 127.0.0.1:7004 slave e24bbe4a46eb20f3a87d496c5451a7a7d81f2ff8 0 1458555570474 5 connected
由此可见,7000、7001、7002是master,其中7005是7002的slave节点,我们尝试将7002关闭,看看7005是否能够正常failover并提升为master:
- #关闭7002
- >./redis-cli -p 7002 shutdown
- ##然后在其他任何节点使用“cluster nodes”指令查看即可
- ##发现7005已经被提升为master
我们可以再次启动7002,会返现此时7002自动转换为7005的slave。从简单测试来看,Cluster的failover机制符合预期的。
如果需要人为的Failover,比如希望将某个Slave提升为Master,我们可以在指定的slave上使用“CLUSTER FAILOVER”指令即可。
新增节点
这是一个非常普遍的运维操作,我们将一个新的node添加到集群中,如果它是一个master节点,还可以将其他nodes上的部分slots迁移到此node上;当然也可以为现有的master新增slave节点。
假如我们新增一个节点7006,它将作为一个新的master加入集群,换个其他节点一下,我们为其准备配置文件和数据目录,并启动:
- > ./redis-server ../redis-7006.conf
- > ./redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
- ##等同于:CLUSTER MEET
“add-node”指令第一个参数为新node的地址,第二个参数为任意现存的节点作为登陆节点。执行后,我们可以通过“cluster nodes”指令查看集群节点的状态,会发现7006加入集群正常,但是唯一的问题就是其上没有分布任何slots;像这种没有任何slots的节点,也不会参与集群选举,它的失效也不会影响集群可用性,所以,我们可以使用上述的“reshard”指令将其他节点的部分slots迁移到新节点。
我们也可以通过如下命令为集群添加一个slave:
- > ./redis-trib.rb add-node --slave 127.0.0.1:7006 127.0.0.1:7000
通过“--slave”选项表示添加的新节点是一个slave,Cluster将这个新节点分配给某个没有slave或者slaves个数最少的master;如果希望为指定的master新增slave节点,则指令中应该指定master节点的ID:
- > ./redis-trib.rb add-node --slave --master-id 545d7cfe420163529962911fe244d356140e3756 127.0.0.1:7006 127.0.0.1:7000
- ##等同于:CLUSTER REPLICATE
移除节点
- > ./redis-trib del-node 127.0.0.1:7000 26f047b573ed2bb37aa6dd46f6e444d3a8e26f50
“del-node”指令可以将一个空的node移除集群,所谓空node就是此node上没有覆盖任何slots。如果你要移除一个master,那么首先需要将此节点上的所有slots迁移到其他nodes上(reshard指令),否则移除节点将会抛出错误。
副本迁移(migration)
我们也会经常遇到这样的需求,将某个master的其中一个slave迁移到其他master,即重新配置slave从属:
- #登陆到相应的slave节点
- CLUSTER REPLICATE <master-node-id>
不过对于集群而言,有时候我们希望slave能够自动迁移到合适的master下,不需要人工干预,这种机制称为“副本迁移”(replicas migration)。
1)集群总是将slaves数量最多的master下的某个slave,迁移到slave个数最小的master下。即平衡每个master持有的slaves数量。
2)通常我们可以将多个slave随意加入集群,而不需要关注它们究竟归属哪个master;因为副本迁移机制,可以动态平衡它们。
3)配置参数“cluster-migration-barrier”用于限定每个master下应该保留的最少slaves个数,那么在副本迁移时,集群应该首先保证当前master下的slaves个数不低于此值。
八、Cluster常用指令
1、CLUSTER NODES
在集群中的任何一个节点,均可以使用此指令查看集群节点的状态和拓扑结构,同时也能查看每个节点分配的slots等。
- db73a3954ccbbae1817bc7c74c7e6f14b66aa3c3 127.0.0.1:7002 slave a91205008a4f0b5a1c0aff5d08f9d903f1d72182 0 1458565075747 7 connected
- a91205008a4f0b5a1c0aff5d08f9d903f1d72182 127.0.0.1:7005 master - 0 1458565075245 7 connected 10923-16383
每条记录的组成:
1)node ID:40个字符的随机字符串,全局唯一。
2)ip:port:节点的地址
3)flags:一个有“,”分割的列表:myself,master,slave,fail?,fail等;master:表示当前node为master,通常其后跟一个“-”;myself表示此node为当前登陆节点;slave表示其节点为slave,此后紧跟master的node ID;fail?:表示节点处于PFAIL状态;fail:此节点处于FAIL状态,多数节点已不可达。
4)ping-sent:此节点最近一次ping发送的时间戳。
5)pong-recv:此节点最近一次pong的接收时间。
6)config-epoch:此节点的epoch值,每次failover,都会导致epoch值的增加。同一个master的多个slaves,在failover时,epoch值最大者被提升为新的master。
7)link-state:链接状态
8)slot:此节点上持有的sltos的区间,如果只持有一个slot,此时将会是一个数字。
2、CLUSTER SLAVES <node-id>:列出指定node的slaves列表。
3、CLUSTER SLOTS:展示出slots与nodes的对应关系
- 1) 1) (integer) 10923 ----start slot range
- 2) (integer) 16383 ----end slot range
- 3) 1) "127.0.0.1" ----master
- 2) (integer) 7005
- 4) 1) "127.0.0.1" --slave
- 2) (integer) 7002
- 2) 1) (integer) 0
- 2) (integer) 5460
- 3) 1) "127.0.0.1"
- 2) (integer) 7000
- 4) 1) "127.0.0.1"
- 2) (integer) 7003
4、CLUSTER KEYSLOT <key>:计算此key所属的slot。
5、CLUSTER MEET <ip> <port>:将指定的redis实例加入集群,当前登陆节点会将此新node的信息通过gossip协议广播给集群中其他的节点。
6、CLUSTER REPLICATE <node-id>:将当前节点转换为指定node的slave。
7、CLUSTER FAILOVER [force | takeover]:将当前节点提升为master。
其他更多指令请参见:CLUSTER
参考文档:
http://redis.io/topics/cluster-tutorial
http://redis.io/topics/cluster-spec