1.影响通信开销的节点数每秒从本地实例列表中选择5个节点,在这5个节点中选择最长时间未通信的实例,发送一个PING消息到实例。即:定时发送PING报文的节点数=5。为了避免部分实例节点始终不能被选中,会有定时任务扫描的备份措施。集群以每秒10次的固定频率扫描本地缓存节点列表,即每100ms扫描一次。如果一个节点:PONG更新时间node.pong_received>(cluster-node-timeout/2)立即向该节点发送PING报文,假设数量为N。即:底层发送的节点数=10*N.通信节点数可以通过增加cluster_node_timeout来减少,例如:从15秒调整为30秒。但是如果cluster_node_timeout过大,会影响发现故障的时间和发现新节点的时间。消息大小一个通信包含一个消息头和一个消息体。消息头:PING消息头比较固定,发送节点主要占用的slot(myslots[CLUSTER_SLOTS/8])占用2KB。消息体:会携带一定数量的其他节点信息,默认包含集群节点总数的1/10,集群最少3个节点,最多-2个节点在集群中。消息体clusterMsgDataGossip的各个字段的字节大小一共是104字节。属性大小charnodename[CLUSTER_NAMELEN]40字节uint32_tping_sent4字节uint32_tpong_received4字节charip[NET_IP_STR_LEN]46字节uint16_tport2字节uint16_tcport2字节uint16_tflags2字节uint16_tpport保留字段uint16_tnotused14字节总计104字节对于一个200节点集群,一个通信成本:2KB消息头+2KB消息体(20*104)=4KB,8KB来回一次。携带的消息体大小与集群规模有关。规模越大,消息体越大,通信成本越高。达到一定程度后,集群整体性能会下降。RedisCluster官方建议最大规模为1000个实例,但在实践中,通常不会超过500个实例。2.伸缩和槽迁移节点伸缩本质上是槽在节点之间的迁移。节点扩容后,需要将原节点上的slot迁移到新节点上。如下图,当节点4加入集群后,节点1的Slo01、节点2的Slot04、节点3的Slot07迁移到节点4,实现数据平衡。在缩容节点之前,需要先将节点上的槽迁移到下线。如下图所示,当集群中的节点4下线时,需要先迁移掉其槽位Slot01、Slot04、Slot07。槽迁移命令包括:??ADDSLOTS、DELSLOTS、FLUSHSLOTS、SETSLOT。3.请求路由和重定向数据存储在槽中,槽分布在实例上。处理客户端请求也是一个寻找对应slot的过程。请求重定向请求路由过程如下:@1客户端向集群中任意节点发送请求命令@2计算key对应的slot,计算公式:slot=CRC16(key)&16383@3slot为在本节点上,执行命令,每个实例维护自己负责的slot,维护其他实例负责的slot@4slot不在本节点,回复MOVE给其他节点信息点@5向目标发起请求node为了减少MOVE重定向的开销,比如Jedis在客户端实现缓存时定义了槽和节点的关系,减少了通信开销。但是,这也增加了客户端的复杂性。客户端将为集群中的每个节点拥有一个独立的连接池。当集群很大时,会占用更多的本地缓存。ASK重定向如果访问的slot正在迁移,一部分数据在源节点,另一部分已经迁移到目标节点,这个过程是怎样的?ASK重定向过程:@1发送请求命令@2计算key@3对应的slot。槽在这个节点,数据也在。正在迁移执行命令@4访问的数据,向目标节点@5发送包含请求数据的ASK报文,目标节点发起ASKING请求,执行命令获取数据。ASK重定向是临时的。客户端(Jedis)收到回复后不会更新客户端槽和节点映射,而MOVE重定向会更新本地槽映射关系。
