当前位置: 首页 > news >正文

【Redis从入门到精通】第44篇:Sentinel启动与监控——它是怎么盯着主服务器的

上一篇【第43篇】Redis Sentinel——主从集群的守门员
下一篇【第45篇】主观下线和客观下线——Sentinel怎么判断主库挂了


上一篇我们认识了Sentinel的功能和配置,但还有一个核心问题没回答:Sentinel到底是怎么"盯着"主库的?它是怎么发现从库的?Sentinel之间又是怎么互相认识的?今天我们深入源码级别,拆解Sentinel的启动初始化和信息收集机制。

一、Sentinel初始化的5个步骤

当你执行redis-sentinel sentinel.conf时,Sentinel的启动过程分为5步:

┌───────────────────────────────────────────────────┐ │ Sentinel 启动初始化流程 │ ├───────────────────────────────────────────────────┤ │ │ │ ① 初始化Redis服务器基础结构 │ │ (和普通Redis启动一样:加载配置、初始化数据结构) │ │ │ │ │ ▼ │ │ ② 将普通Redis服务器代码替换为Sentinel专用代码 │ │ (换命令表、关闭RDB/AOF、换定时器函数) │ │ │ │ │ ▼ │ │ ③ 初始化Sentinel专用状态 │ │ (创建sentinelState结构体) │ │ │ │ │ ▼ │ │ ④ 根据sentinel.conf中的配置,初始化主库列表 │ │ (创建sentinelRedisInstance) │ │ │ │ │ ▼ │ │ ⑤ 创建到主库的命令连接和订阅连接 │ │ (开始监控) │ │ │ └───────────────────────────────────────────────────┘

步骤②非常关键——Sentinel把普通Redis服务器的命令表换掉了。普通Redis支持几百个命令,而Sentinel只支持几个:

普通Redis命令表: Sentinel命令表: ┌─────────────┐ ┌─────────────┐ │ GET │ │ PING │ │ SET │ │ SENTINEL │ │ HSET │ │ SUBSCRIBE │ │ LPUSH │ │ UNSUBSCRIBE │ │ ZADD │ │ PSYNC │ │ ... (200+) │ │ PUBLISH │ │ │ │ INFO │ └─────────────┘ └─────────────┘ (仅7个)

二、sentinelState与sentinelRedisInstance——核心数据结构

Sentinel的内部状态主要通过两个C结构体管理:

sentinelState(Sentinel全局状态)

structsentinelState{charmyid[CONFIG_RUN_ID_SIZE+1];/* 当前Sentinel的运行ID */uint64_tcurrent_epoch;/* 当前纪元(用于Raft选举)*/dict*masters;/* 主库字典:key=主库名, value=sentinelRedisInstance */inttilt;/* 是否进入TILT模式 */intrunning_scripts;/* 正在执行的脚本数量 */mstime_ttilt_start_time;/* TILT模式开始时间 */mstime_tprevious_time;/* 上次执行时间处理器的时间 */list*scripts_queue;/* 待执行脚本队列 */};

sentinelRedisInstance(被监控的Redis实例)

typedefstructsentinelRedisInstance{intflags;/* 实例状态标志:SRI_MASTER/SRI_SLAVE/SRI_SENTINEL等 */char*name;/* 实例名称 */char*runid;/* 实例的运行ID */uint64_tconfig_epoch;/* 配置纪元 */sentinelAddr*addr;/* 实例地址:IP + 端口 */mstime_tdown_after_period;/* 主观下线超时时间 */intquorum;/* 客观下线所需票数 */intparallel_syncs;/* 故障转移后同时同步的从库数 */mstime_tfailover_timeout;/* 故障转移超时时间 *//* 主库专用字段 */dict*sentinels;/* 监控该主库的其他Sentinel */dict*slaves;/* 该主库的从库 */intfailover_state;/* 故障转移状态 */intfailover_state_change_time;/* 状态变更时间 *//* 从库专用字段 */sentinelRedisInstance*master;/* 指向主库实例 */mstime_tmaster_link_down_time;/* 与主库断开的时长 *//* 连接相关 */redisAsyncContext*cc;/* 命令连接 */redisAsyncContext*pc;/* 订阅连接 */mstime_tlast_pub_time;/* 上次发布消息时间 */mstime_tlast_pong_time;/* 上次收到PONG时间 */}sentinelRedisInstance;

关键字段解读:

字段说明
flags实例类型和状态,如SRI_MASTERSRI_SLAVESRI_S_DOWN(主观下线)
name主库有名字(sentinel.conf中定义),从库和Sentinel用ip:port作为名字
runid实例的运行ID,空则表示还未获取到
addr实例的IP和端口
quorum触发客观下线的最少Sentinel数

三、Sentinel发现从库:INFO命令的妙用

Sentinel初始只知道主库的地址,从库是它通过INFO命令"发现"的。

Sentinel Master │ │ │ ─── INFO replication ────→ │ 每10秒发送一次 │ │ │ ←── # Replication ────── │ │ role:master │ │ connected_slaves:2 │ │ slave0:ip=192.168.1.102, │ │ port=6380,state=online │ │ slave1:ip=192.168.1.103, │ │ port=6381,state=online │ │ │ │ (解析INFO输出,发现2个从库) │ │ (为每个从库创建sentinelRedisInstance)│ │ (建立到从库的命令连接+订阅连接) │

解析INFO输出后,Sentinel会:

  1. 提取每个从库的IP和端口
  2. 检查该从库是否已经在自己的slaves字典中
  3. 如果不在,创建新的sentinelRedisInstance并建立连接

踩坑提示:从库的IP地址由主库的INFO输出决定。如果从库配置了replica-announce-ip,Sentinel使用该IP;否则使用从库与主库建立连接时的IP。在Docker/NAT环境中,可能需要显式配置replica-announce-ipreplica-announce-port,否则Sentinel可能连接不到从库。

四、Sentinel互相发现:sentinel:hello频道

Sentinel之间通过主库的发布/订阅频道__sentinel__:hello互相发现:

Sentinel 1 Master Sentinel 2 │ │ │ │ 订阅 __sentinel__:hello │ │─────────────────→│←────────────────│ │ │ │ 订阅 __sentinel__:hello │ │ │ │ 发布 HELLO消息 │ │ │─────────────────→│ │ │ │ 转发 ──────────→│ │ │ │ │ │ ←──── 发布HELLO │ │ ←──── 转发 ─────│ │ │ │ │ │ (互相发现!) │ │

Sentinel每2秒向__sentinel__:hello频道发送一条消息,包含:

消息格式: __sentinel__:hello <sentinel_ip> <sentinel_port> <sentinel_runid> <sentinel_epoch> <master_name> <master_ip> <master_port> <master_epoch>

收到其他Sentinel的消息后:

  1. 如果该Sentinel不在自己的sentinels字典中,添加它
  2. 更新已知Sentinel的信息(IP、端口、epoch等)

五、Sentinel的连接管理

对于每个被监控的主库,Sentinel建立两个连接

Sentinel ─────────────────────→ Master │ │ │ ┌─── 命令连接 (Command Connection) ───┐ │ │ 用途:发送INFO、PING、SENTINEL命令 │ │ └────────────────────────────────────┘ │ │ │ ┌─── 订阅连接 (Subscription Connection) ┐ │ │ 用途:订阅__sentinel__:hello频道 │ │ └─────────────────────────────────────┘

为什么需要两个连接?因为Redis的发布/订阅机制中,一个连接进入订阅状态后就只能执行SUBSCRIBE/UNSUBSCRIBE/PSUBSCRIBE/PUNSUBSCRIBE命令,不能发其他命令。

完整连接关系图:

┌─────────────┐ │ Sentinel │ │ :26379 │ └──┬───┬───┬──┘ │ │ │ ┌──────────┘ │ └──────────┐ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Master │ │ Slave 1 │ │ Slave 2 │ │ 6379 │ │ 6380 │ │ 6381 │ └──────────┘ └──────────┘ └──────────┘ 2个连接 2个连接 2个连接 (cmd+sub) (cmd+sub) (cmd+sub) 另外,Sentinel还会与其他Sentinel建立命令连接 (不需要订阅连接,因为通过主库的频道通信) ┌─────────────┐ │ Sentinel │ │ :26379 │ └──┬───────┬──┘ │ │ ┌─────┘ └─────┐ ▼ ▼ ┌──────────┐ ┌──────────┐ │Sentinel 2│ │Sentinel 3│ │ :26380 │ │ :26381 │ └──────────┘ └──────────┘ 1个连接(cmd) 1个连接(cmd)

六、Sentinel的信息更新频率

Sentinel定期向所有被监控的实例发送命令,频率如下:

目标命令频率说明
主库INFO每10秒发现从库、获取主从状态
从库INFO每10秒确认从库角色和状态
所有实例PING每1秒检测是否在线
主库PUBLISH每2秒__sentinel__:hello发布自身信息
所有SentinelSENTINEL is-master-down-by-addr按需询问其他Sentinel是否认为主库下线
Sentinel 的时间线(1秒精度): 0s 1s 2s 3s ... 10s 11s ... 20s │ │ │ │ │ │ │ PING PING PING PUBLISH PING PING PING all all all hello all all all │ │ │ │ │ │ │ │ │ │ │ INFO │ INFO │ │ │ │ master│ master │ │ │ │ &slaves &slaves

七、TILT模式——Sentinel的自我保护

如果Sentinel检测到系统时间异常(比如系统时间被修改、进程被暂停),它会进入TILT模式

正常模式 TILT模式 ┌──────────────────┐ ┌──────────────────┐ │ 正常监控 │ 时间异常 │ 停止故障转移 │ │ 正常检测下线 │ ────────→ │ 只执行PING/INFO │ │ 可以执行故障转移 │ │ 不做下线判断 │ └──────────────────┘ └──────────────────┘ 持续30秒正常后退出TILT

进入TILT的原因:

  • 两次时间处理器调用之间的时间差为负数或超过2秒
  • 说明系统可能出现进程暂停(如虚拟机暂停、容器冻结)

踩坑提示:在Kubernetes中,如果Pod的CPU被严重限制,可能导致Sentinel进入TILT模式。确保Sentinel有足够的CPU资源。

总结

Sentinel的监控机制是一个精密的信息收集网络:通过INFO发现从库,通过发布/订阅频道发现其他Sentinel,通过PING检测存活状态。每个连接都有明确用途,每种消息都有固定频率。理解这些机制,有助于排查Sentinel的监控盲区和误判问题。

下一篇,我们将深入Sentinel最核心的判断逻辑——主观下线和客观下线,看看Sentinel是如何决定主库"到底挂没挂"的。


上一篇【第43篇】Redis Sentinel——主从集群的守门员
下一篇【第45篇】主观下线和客观下线——Sentinel怎么判断主库挂了


http://www.zskr.cn/news/1458890.html

相关文章:

  • 别再死记硬背!用‘客户服务系统’实战案例,轻松搞懂UML类图与包图设计
  • PHP风控系统与反欺诈策略
  • 新手避坑指南:用BC35-G模块和AT指令,5分钟搞定NBIOT设备上云OneNET
  • FPGA上跑的纯硬件俄罗斯方块:Verilog代码+VGA显示+完整编译工程
  • PHP魔术方法深入理解与实战
  • DeepSeek V4实测:MoE架构与百万上下文的工程真相
  • 从零打造 99.99% 在线 CRM:高可用架构设计与系统化工程方法论
  • 魔兽争霸III终极性能优化:三大核心功能免费解决宽屏适配、地图加载与帧率限制
  • Qwen3.6-Plus工程落地指南:Agent底座的可交付实践
  • AI生成可玩游戏:单文件HTML卡丁车实战指南
  • 从啤酒瓶到二维码:手把手教你复用Gazebo官方模型,打造自定义贴图仿真资产
  • AI工具如何重塑法律服务效率?揭秘2024智能法务整合的7个关键决策点
  • 开源报表工具JimuReport实战:手把手教你配置SQL数据源并生成动态销售报表
  • Spartan-6 FPGA上跑通AD9238双路12位25MHz实时采集的完整ISE工程包
  • 道路积水数据集 路面积水识别数据集 图片数量4524,xml和txt标签都有;公路积水数据集 ✓类别:puddle;
  • 第九章:Token 优化与高效省钱配置(重点)
  • 语义内核形式化模型:AI内容生成的统一数学原理与工程实践
  • Vue版Cesium卫星轨道+雷达扫描三维可视化组件(含CZML数据与小程序适配)
  • 气缸驱动并联机器人位姿控制策略【附仿真】
  • DeepSeek V4实测:百万上下文与MoE架构如何重构AI成本模型
  • 深耕车载数字健康场景,守护全维度驾乘安全与体验
  • GBase 8s数据库高可用之—RHAC远程高可用集群详解
  • 别慌!网站突然打不开显示Error 522?手把手教你排查百度云加速与源站的连接问题
  • 第七章:自定义命令、规则与上下文
  • 仓储软件(WMS)值得推荐的选择方向 - 品牌排行榜
  • 利用快马平台快速构建potplayer字幕翻译工具原型
  • 如何快速定位手机号码归属地:三步完成精准查询
  • 合规红线下的智能外呼:如何用RAG+本地化语音模型通过银保监AI外呼备案(附过审配置清单)
  • Determined:一个集成的深度学习训练平台
  • 计算机重装系统出现SYSTEM磁盘?