Redis学习笔记之集群
建立集群
Cluster MEET IP host 命令用于将指定的ip,host所属的节点添加到当前的集群中。例如客户端连接7000节点,向7000节点发送 CLUSTER MEET 127.0.0.1 7001指令,则7000与7001握手之后,7001加入7000所在的集群中。
具体步骤:
- 收到CLUSTER MEET命令的7000会为7001创建一个clusterNode结构,并且将这个node添加到自己的clusterState.nodes字典里
然后向7001发送一条MEET消息 - 7001如果顺利接收到MEET消息,也会为7000创建一个clusterNode节点然后添加到自己的字典里,随后7001回复一个PONG命令给7000
- 7000如果成功接收到7001命令,回复一个PING命令,握手完成
- 随后7000将7001的信息通过gossip协议传播给集群中的其他节点
clusterNode结构保存了一个节点的当前状态,例如节点地址,节点名字,创建时间等等。每一个节点还保存着一个clusterState结构,这个结构里保存着当前节点视角下集群的其他节点所处的状态。
gossip协议:是一种周期性散播消息的协议,种子节点随机选择几个节点散播消息,接受到消息的节点也会做同样的操作,直到所有的节点都收到了消息,就好像一个八卦在办公室中悄悄传播,最后所有人都知道了的过程,因此称之为gossip协议。gossip协议具有扩展性好,容错率高,去中心化,简单等优点。
槽指派
整个集群有16384个槽用来存放数据,如果所有的槽都被指派给了某个节点管理,那么这个集群就处于上线的状态,否则就处于离线的状态。
-
clusterNode的slots属性和numsslot属性记录了节点负责处理哪些槽
-
slots属性是一个位数组,长度为16384/8,共2048个字节,包含16384个二进制位,负责的槽对应的数组位置值为1,否则为0
-
一个节点除了知道自己负责的槽,还会将自己负责的槽信息传播给其他节点。节点收到其他节点的槽信息时,会在自己的clusterState.nodes字典里找到这个节点对应的clusterNode,然后将信息更新到它的slots属性中。也就是说,集群中的任意一个节点,都保存着这个集群所有的槽指派信息。
-
CLUSTER KEYSLOT <key> 可以查看一个键属于哪个槽
节点计算出当前key所属的槽后,会检查clusterState.slots数组中槽的对应项,而不是查看自己的slots数组,这么做是因为查看 了自己的数组以后如果不是自己负责,那还是得再检查一边clusterState.slots来提示客户端。 -
如果当前指令所属的槽不由自己负责,节点会返回个客户端MOVED错误,并指引客户端指向正确的节点。MOVED命令的格式为:MOVED <slot> <ip>:<port>
-
一个集群客户端通常会与集群的多个节点创立套接字连接,所以客户端接收到MOVED错误以后会转向另一个套接字发送。
-
虽然REDIS有多个数据库可以选择,但是在集群模式中只能使用0号数据库。