Keepalived 不监控数据库主从延迟,需通过自定义健康检查脚本结合复制状态、线程运行情况及GTID一致性综合判断,并利用track_script动态调整权重实现基于延迟的读写分离高可用。

Keepalived 本身不直接监控数据库主从延迟,它只负责 VIP 漂移和节点健康判定。要实现“基于主从延迟的读写分离高可用”,必须把延迟检测逻辑下沉到自定义健康检查脚本中,并让 Keepalived 根据该脚本的退出码(0=健康,非0=异常)动态调整角色权重或触发切换。关键不在 Keepalived 配置本身,而在脚本如何准确、安全地反映延迟状态。
延迟检测脚本需区分角色并验证真实可服务性
不能只查 Seconds_Behind_Master 数值,还要结合复制线程状态、IO/SQL 线程是否运行、是否出现错误等综合判断。例如:
- 对主库:重点检查是否能正常接受写入,延迟无关紧要,但需确认 MySQL 进程存活、端口可达、基础查询响应正常;
- 对从库:必须检查
Seconds_Behind_Master ≤ 30(阈值按业务容忍度设定),且Slave_IO_Running = Yes、Slave_SQL_Running = Yes、Retrieved_Gtid_Set和Executed_Gtid_Set一致(若启用 GTID); - 脚本应使用专用监控账号(如
monitor@'127.0.0.1'),避免密码明文暴露,推荐通过~/.my.cnf配置文件读取凭证; - 每次执行前加超时控制(如
timeout 5 mysql -N -s -e "..."),防止卡死影响 Keepalived 主循环。
Keepalived 配置需启用权重动态调整(nopreempt + track_script)
单纯用 vrrp_instance 的静态 priority 无法响应延迟变化。正确做法是:
- 在
vrrp_instance块中启用track_script,绑定延迟检测脚本; - 脚本返回非 0 时,Keepalived 自动降低本节点优先级(如减 50),触发 VRRP 重选举;
- 主库节点配置
nopreempt为no(默认),确保延迟超标后能被健康从库抢占 VIP; - 从库节点可设较低初始
priority(如 90),主库为 100,避免无谓抢占; - 务必关闭防火墙对 VRRP 协议(IP 协议号 112)的拦截,否则心跳失败导致误切。
读写分离需与 VIP 分离设计,避免单点瓶颈
Keepalived 只管写入口高可用(一个写 VIP),读流量不应也压在同一个 VIP 上。更合理的方式是:
- 部署独立读 VIP(如
192.168.10.100),由另一组 Keepalived 实例管理,专用于从库负载; - 读 VIP 的健康检查脚本只校验从库延迟与复制状态,不涉及主库;
- 应用层连接池配置两个数据源:写地址指向写 VIP,读地址指向读 VIP;
- 若需更精细分流(如按 SQL 类型或权重),应在中间件层(如 ProxySQL、MySQL Router)完成,Keepalived 不参与 SQL 解析。
故障恢复后需人工或半自动干预同步状态
Keepalived 切换后,原主库恢复时不会自动变回主库,也不会自动重做复制关系。必须:
- 确认原主库已追平延迟,且复制 IO/SQL 线程正常;
- 手动停止其复制(
STOP SLAVE),将其设为新主库的从库(CHANGE MASTER TO ...); - 若采用 GTID,可简化为
SET GLOBAL gtid_purged = '...'; START SLAVE;; - 更新 Keepalived 配置中对应节点的
priority和脚本路径,重启服务使其重新参与选举; - 建议配合 MHA 或 Orchestrator 等工具自动化上述步骤,Keepalived 专注网络层兜底。

















