redis设计之集群分析

集群由redis服务器节点组成,通过节点间互相meet握手构成集群

节点握手:

两次握手过程如下所示:

收到meet命令的节点A将会与节点B进行握手,以此来确认彼此的存在

节点A将会为节点B创建一个 clusterNode结构,并将该结构添加到自己的clusterState.nodes字典

节点B收到节点A的MEET,B为A创建一个clusterNode结构,并将该结构添加到自己的clusterState.nodes

之后节点B向节点A返回pong

节点A收到pong,表示节点B收到了A的meet,然后A向B发送ping,

节点B收到A的ping表示,B知道了A已经收到了B的pong,握手完成

槽指派

16384个槽,任意一个槽都需要被节点处理,当存在槽未被指派给节点处理,集群处于下线状态

节点的槽指派信息的记录与传播

redis通过clusterNode结构中的slots和numslot属性来记录槽指派信息

slots是一个二进制位数组,一共16384个二进制位,即slots数组的长度为16384/8=2048

redis从0到16383进行索引编号,即slots[i]上有8个索引,索引处为1说明节点负责处理槽i,为0说明节点不负责处理此处槽i

数组管理槽使得redis处理槽或者查看槽得时间复杂度都为O(1)

numslot属性表示节点管理得槽得数量,即slots中为1的二进制位的个数

节点会通过消息把自己的slots数组发送给别的节点,收到slots数组的节点就会将数组保存到相应节点的clusterNode结构中,因此,集群中每个节点都知道16364个槽的分配情况

clusterState结构中的slots数组记录集群中所有16384个槽的指派信息

如果slots[i]指针指向null,表示槽i尚未指派给人和街店

如果slots[i]指针指向一个clusterNode结构,表示槽i指派给了clusterNode结构所代表的节点

使用clusterState结构中的slots数组的意义:若是想知道槽i是否被指派或者被指派给哪个节点,只使用clusterNode结构中的slots数组的话,就需要O(n),使用clusterState结构中的slots,只需要访问clusterState.slots[i],时间复杂度为O(1)

同样clusterNode节点也是有优势的:当节点需要发送给别的节点自己的槽指派信息的时候,只需要发送clusterNode的slots数组,不然的话还得去clusterState中的slots数组去遍历找自己负责的槽是那些,会低效很多

在集群中执行命令

接受命令的节点会计算出命令要处理的数据库键处于哪个槽,并检查这个槽是否指派给了自己

如果键所在槽指派给自己,直接执行;否则给客户端返回一个MOVED错误,指引客户端转向至正确的点,并再次发送之前想要执行的命令

计算键属于哪个槽的方法:CRC16(KEY) && 16383

而CRC16(key)计算key的校验和,&16383计算出一个介于0至16383的整数作为key的槽号

如果clusterState.slots[i]等于clusterNode.myself,直接执行,否则的话,根据clusterState.slots[i]指向的clusterNode结构中的ip和端口号,向客户端发送MOVED错误。

使用跳表保存键和槽的关系

重新分片

重新分片可以在线进行,即将已经指派给某个节点的槽(包括槽所属的键值对)转为指派给另一个节点

重新分片过程:

让目标节点准备好导入槽slot键值对

让源节点准备迁移槽slot键值对

迁移键值对,(每次最多count,重复直至完成)

将槽slot指派给目标节点

ASK错误

重新分片的过程中,若是客户端发送命令过来,该命令命中还未迁移的键值对时,正常执行返回,若是命中部分已经迁移到了目标节点,向客户端发送一个ASK错误,同时引导客户端导向目标节点

ASK和MOVED区别

MOVED可以认为是责任转移,即后边的客户端继续访问槽i,会直接落到目标节点上去

ASK则只会在接下来的一次请求中落到目标节点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值