上节我们看过了sentinel协调者模块处理集群故障节点的功能,今天我们看一下sentinel的处理架构以及sentinel的初始化流程。
首先,sentinel是独立于数据节点之外的一个协调模块,sentinel不存储任何用户要求存储的key-value数据,sentinel只负责监视集群中每一个节点的运行状态以及处理故障转移。
首先sentinel其实就是redis进程的另一种模式,在Makefile里可以看出来,
# redis-server
$(REDIS_SERVER_NAME): $(REDIS_SERVER_OBJ)
$(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/lua/src/liblua.a $(FINAL_LIBS)
# redis-sentinel
$(REDIS_SENTINEL_NAME): $(REDIS_SERVER_NAME)
$(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME)
首先把所有的object编译,然后把所有的中间文件链接成为$(REDIS_SERVER_NAME),就是redis-server,然后安装的时候直接把redis-server安装成为redis-sentinel。
我们首先看看sentinel的数据结构
/* sentinel主要状态结构体. */
struct sentinelState {
uint64_t current_epoch; /* 当前的选举纪元,用于故障转移 */
dict *masters; /* sentinel正在监视的master实例哈希表,key是实例名称,value是sentinelRedisInstance指针 */
int tilt; /* tilt模式 */
int running_scripts; /* 当前正在执行的脚本数目. */
mstime_t tilt_start_time; /* titl启动时间. */
mstime_t previous_time; /* 上一次执行时间处理函数. */
list *scripts_queue; /* 脚本执行队列. */
char *announce_ip; /* 如果不是NULL,就代表通过gossip协议向此节点扩散. */
int announce_port; /* 如果不为0,就会被其他节点扩散 */
} sentinel;
然后我们再看看sentinelRedisInstance结构体,在sentinel中,每一个redis的主节点或者从节点,sentinel节点都会有一个此结构体表示
typedef struct sentinelRedisInstance {
int flags; /* 当前实例的类型 */
char *name; /* 实例名称. */
char *runid; /* 本实例的运行时ID. */
uint64_t config_epoch; /* 配置的初始选举纪元. */
sentinelAddr *addr; /* 实例的地址 */
…………………………………………………
/* 针对监视的master节点独有的. */
dict *