Redis集群(二)集群数据结构


struct clusterNode {
    // 创建节点的时间
    mstime_t ctime;
    // 节点的名字,由40个字十六进制字符串组成
    char name[REDIS_CLUSTER_NAMELEN];
    // 节点的标识,使用各种不同的标识值记录节点的角色(比如主节点或者从节点),以及节点目前所处的状态(比如在线或者下线)
    int flags;
    // 节点当前的配置纪元,用于实现故障转移
    uint64_t configEpoch;
    // 节点IP地址
    char ip[REDIS_IP_STR_LEN];
    // 节点的端口号
    int port;
    // 保存连接节点所需的有关信息
    clusterLink *link;
    // 二进制位数组,记录节点负责处理哪些槽
    unsigned char slots[16384/8];
    // 记录节点负责处理的槽的数量,即是slots数组中值为1的二进制位的数量
    int numslots;
    // 如果这是个从节点,指向要复制的主节点的clusterNode结构
    struct clusterNode *slaveof;
    // 正在复制这个主节点的从节点数量
    int numslaves;
    // 一个数据组,每个数组项指向一个正在复制这个主节点的从节点的clusterNode结构
    struct clusterNode **slaves;
    // 一个链表,记录了所有其他节点对该节点的下线报告, 每个下线报告由一个clusterNodeFailReport结构表示
    list *fail_reports;

};

typedef struct clusterLink {
    // 连接的创建时间
    mstime_t ctime;
    // TCP 套接字描述符
    int fd;
    // 输出缓冲区,保存着待发送给其他节点的消息(message)
    sds sndbuf;
    // 输入缓冲区,保存着从其他节点接收到的消息
    sds rcvbuf;
    // 与这个连接相关联的节点,如果没有的话就为NULL
    struct clusterNode *node;
} clusterLink;

struct clusterNodeFailReport {
    // 报告目标节点已经下线的节点
    struct clusterNode *node;
    // 最后一次从node节点收到下线报告的时间
    // 程序使用这个时间戳来检查下线报告是否过期
    // (与当前时间戳相差太久的下线报告会被删除)
    mstime_t time;
}

typedef struct clusterState {
    // 指向当前节点的指针
    clusterNode *myself;
    // 集群当前的配置纪元,用于实现故障转移
    unit64_t currentEpoch;
    // 集群当前的状态:是在线还是下线
    int state;
    // 集群中至少处理着一个槽的节点的数量
    int size;
    // 集群节点名单(包括myself节点),字典的键为节点的名字,字典的值为节点对应的clusterNode结构
    dict *nodes;
    // 记录了集群中所有16384个槽的指派信息
    clusterNode *slots[16384];
    // 使用跳跃表保存槽和键之间的关系
    zskiplist *slots_to_keys;
    // 记录当前节点正在从其他节点倒入的槽
    clusterNode *importing_slots_from[16384];
    // 记录当前节点正在迁移至其他节点的槽
    clusterNode *migrating_slots_to[16384];

} clusterState;

备注

  1. 以上内容是根据黄健宏老师的《Redis设计与实现》一书的个人总结与实践。