Redis 从 0 到 1(九):主库宕机 30 秒自动切主——1 主 2 从 3 哨兵 + Go 客户端
我不会起名字322· 后端 / 算法 / 数据库 技术栈 力扣 Hot100 Go 项目 Redis MySQL文章目录Redis 从 0 到 1九主库宕机 30 秒自动切主——1 主 2 从 3 哨兵 Go 客户端一、现象凌晨 3 点主库挂了值班同学手忙脚乱二、docker-compose 搭建 1 主 2 从 3 哨兵收藏点 1三、故障转移全流程30 秒里发生了什么四、哨兵 5 个核心参数收藏点 2五、Go 实操哨兵客户端收藏点 3六、部署与排查清单七、总结Redis 从 0 到 1九主库宕机 30 秒自动切主——1 主 2 从 3 哨兵 Go 客户端上一篇《Redis 从 0 到 1八读写分离读到旧值——主从延迟 4 来源与 Go 探测器》我们量化了主从复制延迟链接https://blog.csdn.net/2501_92769340/article/details/167399552 。本篇解决下一个问题主库宕机谁来切主——答案是哨兵Sentinel。一、现象凌晨 3 点主库挂了值班同学手忙脚乱人工切主的典型现场告警 → 登录服务器 →REPLICAOF NO ONE把从库升主 → 其他从库指向新主 → 改配置、重启应用……顺利的话十几分钟中间业务要么报错要么读旧数据。哨兵做三件事把这个流程压到 30 秒内监控持续探测主从健康、通知故障时发事件、自动故障转移选一个新主、让其他从库重新跟随、广播新主地址。本篇用一份 docker-compose 把它完整跑起来。二、docker-compose 搭建 1 主 2 从 3 哨兵收藏点 1services:redis-master:image:redis:7.2-alpinecommand:redis-server--appendonly yesports:[6379:6379]redis-replica1:image:redis:7.2-alpinecommand:redis-server--appendonly yes--replicaof redis-master 6379redis-replica2:image:redis:7.2-alpinecommand:redis-server--appendonly yes--replicaof redis-master 6379sentinel1:image:redis:7.2-alpinecommand:redis-server /etc/sentinel.conf--sentinelvolumes:[./sentinel1.conf:/etc/sentinel.conf]sentinel2:image:redis:7.2-alpinecommand:redis-server /etc/sentinel.conf--sentinelvolumes:[./sentinel2.conf:/etc/sentinel.conf]sentinel3:image:redis:7.2-alpinecommand:redis-server /etc/sentinel.conf--sentinelvolumes:[./sentinel3.conf:/etc/sentinel.conf]sentinel.conf 三份内容相同换端口即可port 26379 sentinel monitor mymaster redis-master 6379 2 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1dockercompose up-d# 验证哨兵视角dockerexecsentinel1 redis-cli-p26379SENTINEL master mymasterdockerexecsentinel1 redis-cli-p26379SENTINEL replicas mymastermonitor ... 2的 2 是法定人数quorum至少 2 个哨兵都认为主库挂了才判定客观下线。3 个哨兵配 2 是标准搭配容忍 1 个哨兵自己脑抽。三、故障转移全流程30 秒里发生了什么dockerkillredis-master# 模拟主库宕机dockerexecsentinel1 redis-cli-p26379SENTINEL master mymaster# 观察 Info 里的 flags: odown - 等待几秒 - 新主的 IP 出现在输出里时间线默认参数下约 20~40 秒阶段耗时动作SDOWN5s单个哨兵连续 5 秒 PING 不通 → 主观下线ODOWN0s达到 quorum 个哨兵 SDOWN → 客观下线准备选举哨兵选举 leader数秒哨兵们互相投票选出一个来执行切换选新主秒级从在线从库中挑优先级高replica-priority 小、复制偏移量最大、runid 最小的切换秒级对新主REPLICAOF NO ONE其他从库REPLICAOF 新主旧主复活后被降级为新主的从库四、哨兵 5 个核心参数收藏点 2参数默认含义与调优down-after-milliseconds30000多久 PING 不通算主观下线。5 秒意味着网络抖动 5s 就会触发一次不必要切换太小会惊群切换常用 5~10squorummonitor 末位—判定客观下线需要的哨兵数。3 哨兵配 2failover-timeout180000一次切换的超时与两次切换的最小间隔同一次故障期间不会反复切parallel-syncs1切换时几个从库同时向新主全量同步。设大会加速但会打爆网络replica-priority从库侧100选主优先级数字小的优先不想被选中设为 0五、Go 实操哨兵客户端收藏点 3应用侧不需要自己连三个哨兵做发现——go-redis 的 FailoverClient 会packagemainimport(contextfmttimegithub.com/redis/go-redis/v9)funcmain(){rdb:redis.NewFailoverClient(redis.FailoverOptions{MasterName:mymaster,SentinelAddrs:[]string{127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381},Password:redis123,DialTimeout:3*time.Second,ReadTimeout:2*time.Second,WriteTimeout:2*time.Second,PoolSize:20,MaxRetries:3,// 切换窗口内的命令由重试兜底})deferrdb.Close()ctx:context.Background()fori:0;i10;i{iferr:rdb.Set(ctx,sentinel:probe,i,time.Minute).Err();err!nil{fmt.Printf([%d] 写入失败切主窗口内属正常: %v\n,i,err)}else{v,_:rdb.Get(ctx,sentinel:probe).Result()fmt.Printf([%d] 当前主库读回: %v\n,i,v)}time.Sleep(time.Second)}}测试运行程序的同时docker kill redis-master观察输出——中间 1~3 次写入失败No route to host / connection refused随后自动恢复。这就是无感的真相有几秒窗口靠客户端重试吃掉。要想零失败业务层需要读旧值容忍或本地队列缓冲第 31 篇脑裂还会再谈切换期数据。FailoverClient 与第 2 篇普通 Client 的区别启动时向哨兵问现在谁是主拿到主地址后直连主变更时会重新询问。它不连哨兵转发流量哨兵只当查号台。六、部署与排查清单命令作用SENTINEL master mymaster查看主库状态、当前地址、SDOWN/ODOWN 标记SENTINEL replicas mymaster查看从库列表与偏移量SENTINEL sentinels mymaster查看其他哨兵确认两两可达防止半数分区误判SENTINEL ckquorum mymaster检查当前可达法定人数部署后必跑INFO sentinel哨兵上哨兵自己的视角部署检查 4 步ckquorum通过证明没有哨兵网络孤岛杀掉一个哨兵告警与切换仍正常杀掉主库计时从 ODOWN 到新主可写旧主复活确认它被自动降级为从库、没有两个主脑裂残留第 31 篇详谈。七、总结哨兵 监控 通知 自动故障转移3 个哨兵 quorum2 是标准配置切主默认 20~40 秒无感靠客户端重试吃下切换窗口down-after-milliseconds 在快速切换和避免惊群之间取舍Go 侧用 FailoverClient让查号自动化。下一篇预告哨兵解决了高可用但单实例的内存和吞吐天花板还在——10 万 QPS、几百 GB 数据怎么扩下一篇《16384 个槽怎么分6 节点 Cluster 与 Go 重定向处理》我们进入分片时代。

相关新闻

第 9 篇 · 数值计算与图像处理:NumPy、SciPy、Pillow

第 9 篇 · 数值计算与图像处理:NumPy、SciPy、Pillow

数值计算与图像处理:NumPy、SciPy、Pillow 数据分析链路中,除表格处理外还涉及两类底层能力:数值计算(数组运算、线性代数、插值与优化、信号处理)与图像处理。本节以 NumPy、SciPy、Pillow 三个库为例,说…

2026/10/15 3:56:45 阅读更多 →
【学习记录】DAP调试器电路原理图完全详解:从STM32最小系统到SWD调试接口

【学习记录】DAP调试器电路原理图完全详解:从STM32最小系统到SWD调试接口

【学习记录】DAP调试器电路原理图完全详解:从STM32最小系统到SWD调试接口 DAP调试器(CMSIS-DAP)是嵌入式开发中最常用的调试工具之一。它本质上是一个小型的STM32最小系统 USB接口 目标调试接口。本文从原理图角度,逐模块拆解DA…

2026/10/15 3:56:45 阅读更多 →
Python做微信机器人:个人微信API最小收发闭环实战

Python做微信机器人:个人微信API最小收发闭环实战

用 Python 做微信机器人,最常见的起步方式是:找个示例、复制一段发送代码、在测试好友上点一点。 能发出去当然高兴,但一接到真实业务——自动回、CRM、AI——就会发现:收不稳、回双份、偶发找不到人。 个人微信 API 实战&#x…

2026/10/15 3:56:45 阅读更多 →

最新新闻

模板代码生成工具:从元数据到可用接口的完整实现

模板代码生成工具:从元数据到可用接口的完整实现

1. 为什么需要模板代码生成工具:一大半重复代码其实不该手写做后端开发的朋友应该都有过这种体验:新项目启动,建表、写实体、写Mapper、写Service接口和实现、写Controller,然后前端再把列表页、表单页、弹窗、状态标签挨个撸一遍…

2026/10/15 4:45:53 阅读更多 →
桶排序全解析:原理、复杂度与工程实践

桶排序全解析:原理、复杂度与工程实践

1. 从"把数据扔进格子里"说起:桶排序的第一性原理如果你接触排序算法有一阵子,大概率听说过这句话:"桶排序在数据分布均匀的时候能做到接近O(n)"。但很多人学完快排、归并之后,对桶排序的印象只剩下一个模糊的…

2026/10/15 4:45:53 阅读更多 →
ET 200MP模拟量输出模块AQ 4xU/I ST选型接线调试指南

ET 200MP模拟量输出模块AQ 4xU/I ST选型接线调试指南

简介:西门子SIMATIC S7-1500/ET 200MP模拟量输出模块AQ 4xU/I ST设备手册,面向工业自动化领域的工程技术人员、系统集成商与运维人员。内容聚焦模拟量输出模块在制造、能源、交通等场景下的选型、接线、参数设置与调试问题,帮助用户实现精准的…

2026/10/15 4:45:53 阅读更多 →
Windows开机自启全攻略:启动文件夹、注册表、任务计划与服务详解

Windows开机自启全攻略:启动文件夹、注册表、任务计划与服务详解

1. 开机自启这件事,远不止把快捷方式拖进启动文件夹那么简单很多人第一次接触开机自启,都是因为某个小工具每次重启后都要手动打开,烦得不行。于是上网一搜,看到最多的答案就是“把快捷方式拖进启动文件夹”,照做之后确…

2026/10/15 4:45:53 阅读更多 →
基于地点相似度的POI推荐与路径重组MATLAB实现

基于地点相似度的POI推荐与路径重组MATLAB实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 4:45:53 阅读更多 →
延迟优化实战:从毫秒级到微秒级的系统性能提升路径

延迟优化实战:从毫秒级到微秒级的系统性能提升路径

1. 我为什么折腾到微秒级:被延迟拖垮的业务,往往都死得悄无声息很多人做性能优化,跑到“毫秒级”就收工了,觉得接口P99能压到5ms以内已经是了不起的成就。但如果你在真正的高并发业务链路里待过,就会明白:当…

2026/10/15 4:44:53 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →