Redis解析之集群数据结构

Redis是一个高可用、高性能、高可扩展性的基于内存支持持久化存储key-value存储数据库。

集群相关的数据结构:
// cluster.h
// 保存当前节点与其他节点进行通讯所需的全部信息
typedef struct clusterLink {
    // 链接创建时间
    mstime_t ctime; 
    
    // TCP套接字描述符
    int fd;   
    
    // 发送缓冲区,保存等待发送给其他节点的数据
    sds sndbuf;                
    
    // 接受缓冲区,保存从其他节点收到的数据
    sds rcvbuf; 
    
    // 与当前节点相连接的节点
    struct clusterNode *node; 
} clusterLink;

// cluster.h

// 集群节点结构体
typedef struct clusterNode {
    
    // 节点创建时间
    mstime_t ctime;                     
    
    // 节点ID,长度为40,每一个字符都是一个16进制字符,通过随机数生成
    char name[REDIS_CLUSTER_NAMELEN];   
    
    // 节点标识,标识节点是 Master 或 Slave 
    int flags;                          
    
    // 节点当前的配置纪元
    uint64_t configEpoch;               
    
    // REDIS_CLUSTER_SLOTS:整个集群分块的总数目,即16384
    // Slots是一个二进制位数组(bitarray),数组长度为REDIS_CLUSTER_SLOTS/8=2048个字节
    // 位值1表示对应slot的数据存储在当前节点,是0表示不在这个节点。  
    unsigned char slots[REDIS_CLUSTER_SLOTS/8]; 
    
    // 当前节点所分配的 slot 总数
    int numslots; 
    
    // 若当前节点为 Master,则表示相应 Slave 的数据
    int numslaves; 
    
    // 指针数组,指向 Slave 节点
    struct clusterNode **slaves;
    
    // 指正数组,指向 Master 节点
    struct clusterNode *slaveof;
    
    // 最近一次发送 ping包的时间
    mstime_t ping_sent;  
    
    // 最近一次接受 pong包的时间
    mstime_t pong_received;
    
    // 最近一次被设置成 fail状态的时间
    mstime_t fail_time; 
    
    // 最近一次为某个 Salve 投票的时间
    mstime_t voted_time;    
    
    // 最近一次从这个节点接收到复制偏移量的时间 
    mstime_t repl_offset_time;
    
    // 当前节点的复制偏移量 
    PORT_LONGLONG repl_offset;
    
    // 当前节点的 IP
    char ip[REDIS_IP_STR_LEN];
    
    // 当前节点的 Port
    int port;  
    
    // 保存连接相关的信息  
    clusterLink *link;
    
    // 一个链表,记录了所有其他节点对该节点的下线报告 
    list *fail_reports;
    
} clusterNode;

// cluster.h
// 节点状态信息
typedef struct clusterState {
    // 当前节点
    clusterNode *myself;
    
    // 集群当前的配置纪元
    uint64_t currentEpoch;
    
    // 状态标识:OK?FAIL?
    int state;          
    
    // 集群中至少拥有一个 slot 的 Master 的数目
    int size;   
    
    // 整个集群所有节点,键:节点ID,值:clusterNode结构体
    dict *nodes; 
    
    // 节点黑名单
    dict *nodes_black_list;
    
    // 记录从当前节点迁移至目标节点的 slot,以及迁移的目标节点  
    // migrating_slots_to[i] = NULL 表示slot i未被迁移  
    // migrating_slots_to[i] = clusterNode_A 表示slot i要从本节点迁移至节点 A
    // REDIS_CLUSTER_SLOTS:16384
    clusterNode *migrating_slots_to[REDIS_CLUSTER_SLOTS];
    
    // 记录要从源节点迁移到本节点的 slot,以及进行迁移的源节点  
    // importing_slots_from[i] = NULL 表示slot i未进行导入  
    // importing_slots_from[i] = clusterNode_A 表示正从节点 A中导入slot i  
    clusterNode *importing_slots_from[REDIS_CLUSTER_SLOTS];
    
    // 记录各节点所分配的 slot
    // 例如 slots[i] = clusterNode_A表示slot i 由节点 A处理  
    clusterNode *slots[REDIS_CLUSTER_SLOTS];
    
    // 跳跃表
    zskiplist *slots_to_keys;
    
    
    // -------------------以下这些域被用于进行故障转移选举
    // 上次执行选举或者下次执行选举的时间  
    mstime_t failover_auth_time;
    
    // 节点收到的投票数目
    int failover_auth_count;
    
    // True:当前节点已经向其他节点发送投票请求
    int failover_auth_sent; 
    
    // Slave 在当前故障转移选举中的排名
    int failover_auth_rank; 
    
    // 当前选举的纪元
    uint64_t failover_auth_epoch; 
    
    // Slave 不能执行故障转移选举的原因
    int cant_failover_reason;  
    
    
    // -------------------共用的手动故障转移状态
    // 手动故障转移时限
    mstime_t mf_end;           
    
    
    // -------------------Mater 节点的手动故障转移状态
    // Slave 节点
    clusterNode *mf_slave;      
    
    
    // -------------------Slave 节点的手动故障转移状态
    // 指示手动故障转移是否可以开始的标志值  
    PORT_LONGLONG mf_master_offset; 
                                   
    // 非0表示开始为选举 Master 投票                                 
    int mf_can_start;          

    // -------------------以下字段由 Master使用,用于记录选举状态
    // 最近一次投票的纪元
    uint64_t lastVoteEpoch;   
    
    // clusterBeforeSleep() 需要做的事情
    int todo_before_sleep;
    
    // 通过 cluster bus 发送消息的数目 
    PORT_LONGLONG stats_bus_messages_sent;
    
    // 通过 cluster bus 接收消息的数目 
    PORT_LONGLONG stats_bus_messages_received;
    
} clusterState;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值