redis源码浅析--十六.cluster集群的设计与实现

本文深入探讨Redis集群的源码实现,包括节点握手、槽分配、命令执行流程、复制与故障转移机制等内容,并分析集群间消息传递的具体实现。

环境说明:redis源码版本 5.0.3;我在阅读源码过程做了注释,git地址:https://gitee.com/xiaoangg/redis_annotation
如有错误欢迎指正
参考书籍:《redis的设计与实现》

文章推荐:
redis源码阅读-一--sds简单动态字符串
redis源码阅读--二-链表
redis源码阅读--三-redis散列表的实现
redis源码浅析--四-redis跳跃表的实现
redis源码浅析--五-整数集合的实现
redis源码浅析--六-压缩列表
redis源码浅析--七-redisObject对象(下)(内存回收、共享)
redis源码浅析--八-数据库的实现
redis源码浅析--九-RDB持久化
redis源码浅析--十-AOF(append only file)持久化
redis源码浅析--十一.事件(上)文件事件
redis源码浅析--十一.事件(下)时间事件
redis源码浅析--十二.单机数据库的实现-客户端
redis源码浅析--十三.单机数据库的实现-服务端 - 时间事件
redis源码浅析--十三.单机数据库的实现-服务端 - redis服务器的初始化
redis源码浅析--十四.多机数据库的实现(一)--新老版本复制功能的区别与实现原理
redis源码浅析--十四.多机数据库的实现(二)--复制的实现SLAVEOF、PSYNY
redis源码浅析--十五.哨兵sentinel的设计与实现
redis源码浅析--十六.cluster集群的设计与实现
redis源码浅析--十七.发布与订阅的实现
redis源码浅析--十八.事务的实现
redis源码浅析--十九.排序的实现
redis源码浅析--二十.BIT MAP的实现
redis源码浅析--二十一.慢查询日志的实现
redis源码浅析--二十二.监视器的实现

上一篇介绍了redis集群的基础概念、搭建方法。本文接着介绍redis集群的源码设计实现。

一 节点 

1.1 节点数据结构

集群中每个节点都会使用clusterNode结构自己的状态,并为集群中的其他节点都创建一个clusterNode结构记录其他节点状态:

typedef struct clusterNode {
    mstime_t ctime; /* Node object creation time. */ //节点的创建时间
    char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size *///节点的名字,40个十六进制字符
    int flags;      /* CLUSTER_NODE_... */ //节点标识,记录节点角色,节点状态等;
    uint64_t configEpoch; /* Last configEpoch observed for this node *///节点当前配置的纪元,用于实现故障转移
    unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node *///slots是一个二进制数组,数组长度 CLUSTER_SLOTS/8
    int numslots;   /* Number of slots handled by this node */ //记录节点记录的槽的数量

    int numslaves;  /* Number of slave nodes, if this is a master */
    struct clusterNode **slaves; /* pointers to slave nodes */
    struct clusterNode *slaveof; /* pointer to the master node. Note that it
                                    may be NULL even if the node is a slave
                                    if we don't have the master node in our
                                    tables. */
    mstime_t ping_sent;      /* Unix time we sent latest ping */
    mstime_t pong_received;  /* Unix time we received the pong */
    mstime_t fail_time;      /* Unix time when FAIL flag was set */
    mstime_t voted_time;     /* Last time we voted for a slave of this master */
    mstime_t repl_offset_time;  /* Unix time we received offset for this node */
    mstime_t orphaned_time;     /* Starting time of orphaned master condition */
    long long repl_offset;      /* Last known repl offset for this node. */
    char ip[NET_IP_STR_LEN];    /* Latest known IP address of this node */
    int port;                   /* Latest known clients port of this node */
    int cport;                  /* Latest known cluster port of this node. */
    clusterLink *link;          /* TCP/IP link with this node *///保存连接节点有关的信息
    list *fail_reports;         /* List of nodes signaling this as failing */
} clusterNode;

clusterNode中link属性保存了连接节点所需要的有关信息:

/**
 * clusterLink封装了与远程节点通信所需的所有信息。
 */ 
/* clusterLink encapsulates everything needed to talk with a remote node. */
typedef struct clusterLink {
    mstime_t ctime;             /* Link creation time */ //连接创建的时间
    int fd;                     /* TCP socket file descriptor */ //文件描述符号
    sds sndbuf;                 /* Packet send buffer */ //输出缓冲区,保存着等待发送给其他节点的信息
    sds rcvbuf;                 /* Packet reception buffer *///输入缓冲区,保存其他节点发来的信息
    struct clusterNode *node;   /* Node related to this link if any, or NULL */ //与这个连接相关联的节点,没有就null
} clusterLink;

每个服务器都会保存一个clusterState结构(入口server.h/redisServer --> cluster.h/clusterState);用来记录当前集群所处的状态;

typedef struct clusterState {
    clusterNode *myself;  /* This node *///当前节点的指针
    uint64_t currentEpoch; //集群当前配置的纪元,用于实现故障转移
    int state;            /* CLUSTER_OK, CLUSTER_FAIL, ... */ //集群状态 ,上线/下线
    int size;             /* Num of master nodes with at least one slot */
    dict *nodes;          /* Hash table of name -> clusterNode structures */ //集群的节点名单
    dict *nodes_black_list; /* Nodes we don't re-add for a few seconds. */
    clusterNode *migrating_slots_to[CLUSTER_SLOTS];
    clusterNode *importing_slots_from[CLUSTER_SLOTS];
    clusterNode *slots[CLUSTER_S
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值