美文网首页
redis源码阅读之cluster(二) 管理命令及实现

redis源码阅读之cluster(二) 管理命令及实现

作者: tanghui | 来源:发表于2019-02-24 13:45 被阅读0次

    cluster 管理命令及实现

    cluster管理

    cluster reset

    cluster reset [hard|soft]
    

    cluster reset 分为soft reset和hard reset,不指定的情况下为soft
    执行reset后:

    1. 所有节点会被forget
    2. 所有已指派过的slot会被释放清空
    3. node会变更为master
    4. nodes.conf 文件会被更新并且cluster state被修改
    5. 如果node是slave,数据会被flush
    6. (hard) 生成新的nodeid
    7. (hard) epoch 被重置为0

    cluster bumpepoch

    cluster bumpepoch 
    

    这是一个redis的隐藏命令。bumpepoch检查执行命令的节点当前的epoch,并与集群的最大epoch比较,如果当前
    节点的epoch为0,或者小于集群的maxEpoch,则将集群的epoch加1,并且节点的configEpoch设置为等于currentEpoch。

    cluster info

    cluster info
    

    获取当前节点的集群信息,
    包括集群状态 slot分配状态 epoch。

    node管理

    cluster meet

    cluster meet ip port
    

    cluster meet 进行节点间的握手,握手成功后,新节点加入到集群。

    if (!strcasecmp(c->argv[1]->ptr, "meet") && c->argc == 4)
    {
        // 校验ip port正确后开始进行握手
        if (clusterStartHandshake(c->argv[2]->ptr, port) == 0 &&errno == EINVAL)
    }
    
    int clusterStartHandshake(char *ip, int port)
    {
        // ... ip port 合法性校验
        {
             // ip 不合法,返回EINVAL
            errno = EINVAL;
            return 0;
        }
        // 已经处于握手中,返回错误 EAGAIN
        if (clusterHandshakeInProgress(norm_ip, port))
        {
            errno = EAGAIN;
            return 0;
        }
        // 创建cluster node对象
        n = createClusterNode(NULL, CLUSTER_NODE_HANDSHAKE | CLUSTER_NODE_MEET);
        memcpy(n->ip, norm_ip, sizeof(n->ip));
        n->port = port;
        // 将新的node加入到集群。
        // 此时,cluster state的node列表该节点还是处于handshake状态,只有后续心跳同步到其他节点后才会更新节点状态
        clusterAddNode(n);
    }
    

    clusterAddNode只是把node加入到cluster->nodes的map中
    并且flags被设置为handshake|meet。clusterCron任务会向该新节点发起tcp连接,并通过心跳gossip发送meet状态指令,
    发送玩meet后,meet flags会被清空。meet flag被清空后,下一次心跳降发送ping指令,当收到pong响应后,如果该节点还处于
    handshake,则handshake flags将被清空,节点成功加入cluster。

    cluster nodes

    nodes 返回集群所有的节点信息,通过clusterGenNodeDescription生成node 信息的描述
    包括 nodeid ip:port slots 信息

    slot管理

    cluster flushslots

    清空该节点所有已分配的slots,删除node的slot信息。

    cluster addslots|delslots

    cluster addslots [slot] ...
    cluster delslots [slot] ... 
    

    添加删除slot只是简单地更新node的slot标记位,唯一需要注意的是,如果添加的slot处于importing状态
    因为该node已经拥有了这个slot,因此需要清空这个slot的importing状态。

    cluster setslot

    SETSLOT 10 MIGRATING <node ID>
    SETSLOT 10 IMPORTING <node ID>
    SETSLOT 10 STABLE
    SETSLOT 10 NODE <node ID>
    

    cluster setslot 用于在集群节点间的dlot迁移。setslot命令只能在master节点上执行。
    migrating将当前节点的slot迁移到nodeid,

    if (!strcasecmp(c->argv[3]->ptr, "migrating") && c->argc == 5)
    {
        // 必须在当前节点执行
        if (server.cluster->slots[slot] != myself)
        {
            addReplyErrorFormat(c, "I'm not the owner of hash slot %u", slot);
            return;
        }
        // nodeid 必须是已知的节点
        if ((n = clusterLookupNode(c->argv[4]->ptr)) == NULL)
        {
            addReplyErrorFormat(c, "I don't know about node %s",
                                (char *)c->argv[4]->ptr);
            return;
        }
        // 添加migrating节点到migrating slots当中
        server.cluster->migrating_slots_to[slot] = n;
    }
    
    • importing将slot从目标节点nodeid导入到当前节点,相应的该slot不应该属于当前节点。
    • stable回滚slot的迁移状态,清除migrating和importing的标识。
    • node将slot指派给nodeid所在节点,完成指派之前,需要判断当前slot是否还有key,如果还有,则无法完成slot的指派。
      如果当前节点的slot之前处于importing状态,则需要更新epoch,以便slot的更新信息更新为最新的version同步到整个集群。

    相关文章

      网友评论

          本文标题:redis源码阅读之cluster(二) 管理命令及实现

          本文链接:https://www.haomeiwen.com/subject/emovyqtx.html