Redis一站式指南三:用 Docker+Redis 哨兵,教你搞懂自动故障转移

发布时间:2026/10/21 3:24:05
Redis一站式指南三:用 Docker+Redis 哨兵,教你搞懂自动故障转移
一.主从复制中的主节点问题主从复制最大的问题在于主节点。若主节点出现故障从节点虽能提供读操作但无法自动升级为主节点也不能替换原有主节点对应的角色此时需人工程序猿或运维手动恢复主节点过程繁琐。举个栗子~1.断开主节点service redis-service stop2.子节点查看详细还是能查看数据但是依然不能进行修改操作1.1Redis 哨兵自动替换主节点从节点和主节点断开连接的两种情况从节点主动和主节点断开连接slaveof no one意味着要主动修改 Redis 的组成结构此时从节点能够晋升成主节点。主节点挂了从节点不会晋升成主节点必须通过人工干预恢复主节点这是脱离掌控的高可用典型问题。1.2哨兵机制原理哨兵机制通过独立进程体现与 redis - server 是不同进程。redis - sentinel 不负责存储数据只对其他 redis - server 进程起监控作用。通常有多个哨兵节点构成集合单个哨兵节点挂掉不影响整体。实际开发中监控程序的重要性服务器需高可用性7 * 24 小时运行长期运行会有意外不能全靠人工监控。需编写监控程序发现服务器运行异常还需搭配报警程序短信、电话、邮件等及时通知程序猿报警不仅给程序猿还会给其领导。程序猿恢复主节点故障的步骤先查看主节点能否抢救。若主节点无法短时间解决或原因不明挑一个从节点设为新主节点把选中的从节点通过 slaveof no one 自立山头。把其他从节点修改 slaveof 的主节点 ip port连上新主节点。告知客户端修改配置连接新主节点进行数据操作。之前挂掉的主节点修好后可作为新从节点挂到机器中。人工干预的问题人工干预繁琐且易出错恢复过程可能需半小时以上期间 Redis 不能写不合适。1.3Redis 哨兵核心功能监控哨兵进程监控现有的 redis master 和 slave进程间建立 tcp 长连接定期发送心跳包及时发现主机是否挂掉。自动的故障转移若主节点挂掉多个哨兵节点共同认同此事防止误判然后推举一个 leader由 leader 从从节点中挑选新主节点挑选后哨兵节点自动控制被选中节点执行 slaveof no one并控制其他从节点修改 slaveof 到新主节点。通知哨兵节点自动通知客户端程序新主节点是谁客户端后续针对新主节点操作。哨兵节点设置原则在分布式系统中应避免单点哨兵节点最好搞奇数个最少 3 个因为单个哨兵节点易出问题若其挂掉且后续 Redis 节点也挂就无法自动恢复且网络数据易出问题单哨兵节点误判概率高影响大。二.实操环节Redis 哨兵模式里6 个节点3 个哨兵 1 主 2 从 理论上要部署在 6 台不同服务器。这样每个节点独立不会因单机故障、资源冲突影响整个集群保障高可用 。考虑到如果是学生在实际学习或测试时可能只有1 台云服务器只能把 6 个节点塞到同一台机器。但这么做生产环境没意义因为单机故障会让整个集群崩失去高可用价值 纯粹是没办法的妥协 。1.单服务器部署哨兵集群的痛点把多个节点放同一服务器会遇到“资源冲突”问题节点间依赖的端口、配置文件、数据文件容易打架比如多个 Redis 实例都想用 6379 端口直接冲突 。想正常部署得小心翼翼避坑手动改端口、分配置文件路径、隔数据存储目录…… 操作和最开始手动配主从结构一样繁琐而且和 “多服务器部署” 差异极大后续维护、模拟真实场景也麻烦 。2.Docker 解决思路轻量隔离简化部署为解决单服务器多节点冲突问题引入Docker。先理解 Docker 是啥核心实体概念Docker 容器轻量级虚拟机可基于镜像运行隔离应用环境Docker 镜像类似 “可执行程序”容器从镜像创建可自己构建或从 Docker Hub类似镜像仓库有大佬分享的镜像也有 Redis 官方镜像 拉取Docker Compose辅助 Docker 批量管理容器的工具补充镜像和容器关系像 “可执行程序” 与 “进程”镜像静态存配置容器动态运行镜像内容拉取的 Redis 镜像包含精简 Linux 系统 装好的 Redis用它建容器就能直接跑 Redis 服务简化部署一Docker 类比虚拟机但更轻量虚拟机VM在一个电脑上用软件模拟 “新电脑”硬件级隔离 能跑独立系统但特别吃资源要模拟 CPU、内存、硬盘云服务器扛不住多开 。Docker类似 “轻量级虚拟机”隔离应用环境不是硬件级是进程、文件级 不用模拟完整硬件资源占用少。哪怕配置差的云服务器也能轻松开几个 Docker 容器模拟多节点部署 。二Docker 解决单服务器部署痛点用 Docker 给每个节点哨兵、主从 Redis 套个 “容器”每个容器有独立的网络、端口、文件系统 。比如给主 Redis 容器开 6379 端口从 Redis 容器开 6380、6381互不干扰 。配置、数据文件放容器内部或挂载到主机特定目录自动隔离不用手动改一堆路径避冲突 。相当于在 1 台服务器上用 Docker 虚拟出多个 “小环境”模拟多服务器部署的效果还能简化配置、避免冲突 。2.1安装docker和docker-compose核心实体与概念配置文件作用定义要创建的容器、容器运行参数实现批量启动 / 停止容器配置文件格式采用 YAMLyml格式类比 Spring 框架也用 yml 做配置文件应用逻辑通过编写 yml 配置文件描述容器创建信息含容器列表、各容器参数 之后用 Docker Compose 等工具一条命令如docker-compose up -d启动、docker-compose down停止 就能批量管理容器生命周期简化多容器部署运维 。ubantu命令apt install docker-compose2.2停掉之前的redis服务器2.3dockers下载redis镜像docker pull redis5.0.9如果显示连接不了docker hub 按照下列步骤来步骤 1登录阿里云打开 阿里云官网登录你的阿里云账号没有的话先注册一个免费步骤 2找到镜像加速器地址登录后搜索容器镜像服务英文可能是Container Registry进入后在左侧菜单找到镜像加速器这里会显示一个你的专属加速器地址长这样https://xxxxxx.mirror.aliyuncs.com xxxxxx 是你的账号 ID步骤 3配置到 Docker在你的服务器上运行sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json EOF { registry-mirrors: [ 你的阿里云加速器地址 ] } EOF ⚠️ 记得把 你的阿里云加速器地址 换成刚才在阿里云看到的那个地址。步骤 4重启 Dockersudo systemctl daemon-reload sudo systemctl restart docker步骤 5重新拉镜像docker pull redis:5.0.9这次应该会直接从阿里云节点下载速度很快。98.3MB的操作系统部分和 Redis 本体部分2.4.docker-compose来进行容器编排2.4.1创建三个容器作为redis的数据节点一个主两个从mkdir redis在当前目录创建名为 redis 的文件夹用于收纳后续 Redis 相关文件。cd redis切换工作目录到刚创建的 redis 文件夹后续操作在此目录内进行。mkdir redis - data在 redis 文件夹里创建 redis - data 子文件夹常用来存 Redis 数据文件如持久化数据 。mkdir redis - sentinel在 redis 文件夹内创建 redis - sentinel 子文件夹用于放置哨兵模式相关配置、脚本等 。cd redis - data/切换工作目录到 redis - data 文件夹后续操作聚焦于此 。vim docker - compose.yml用 vim 编辑器打开或新建docker - compose.yml 文件用于编写 Docker Compose 的配置定义 Redis 相关服务、部署规则等 。version: 3.7 services: master: image: redis:5.0.9 container_name: redis-master restart: always command: redis-server --appendonly yes ports: - 6379:6379 slave1: image: redis:5.0.9 container_name: redis-slave1 restart: always command: redis-server --appendonly yes --slaveof redis-master 6379 ports: - 6380:6379 slave2: image: redis:5.0.9 container_name: redis-slave2 restart: always command: redis-server --appendonly yes --slaveof redis-master 6379 ports: - 6381:6379 ~ ~查看三个容器是否成功2.4.2创建三个容器作为redis的哨兵节点version: 3.7 services: sentinel1: image: redis:5.0.9 container_name: redis-sentinel-1 restart: always command: redis-sentinel /etc/redis/sentinel.conf volumes: - ./sentinel1.conf:/etc/redis/sentinel.conf ports: - 26379:26379 sentinel2: image: redis:5.0.9 container_name: redis-sentinel-2 restart: always command: redis-sentinel /etc/redis/sentinel.conf volumes: - ./sentinel2.conf:/etc/redis/sentinel.conf ports: - 26380:26379 sentinel3: image: redis:5.0.9 container_name: redis-sentinel-3 restart: always command: redis-sentinel /etc/redis/sentinel.conf volumes: - ./sentinel3.conf:/etc/redis/sentinel.conf ports: - 26381:26379 networks: default: external: name: redis-data_default配置哨兵节点配置文件bind 0.0.0.0 port 26379 sentinel monitor redis-master redis-master 6379 2 sentinel down-after-milliseconds redis-master 1000再复制两份启动docker-compose up -d查看日志:docker-compose logs2.5演示哨兵节点功能rootLHY:~/redis/redis-sentinel# docker ps -a2.5.1停止主节点docker stop redis-master2.5.2查看哨兵节点日志情况Sentinel 发现主节点 redis-master (172.19.0.2:6379) 处于主观下线状态sdown 和 odown也就是 Sentinel 自己判断主节点挂了Sentinel 启动了自动故障转移流程try-failoverSentinel 投票选举主节点领导但投票后失败了-failover-abort-not-elected并且设置了下一次尝试故障转移的延迟Next failover delay2.5.3查看子节点replication谁成了主节点端口 6380 的实例是 从节点role:slave它的主节点是 172.19.0.4:6379连接正常master_link_status:up。端口 6381 的实例是 主节点role:master且有一个从节点连接connected_slaves:1从节点 IP 是 172.19.0.3:6379状态在线。是端口为6381的子节点变成主节点了2.5.4重新启动端口6379节点重写启动命令docker start redis-masterredis-cli -p 6379docker start redis-master启动名为 redis-master 的 Redis 容器确保 Redis 服务运行。redis-cli -p 6379连接本地的 Redis 服务进入交互式命令行方便你查看或操作 Redis。查看6381端口发现变成两个子节点连接了*2.6 哨兵重新选取主节点的流程2.6.1 主观下线2.6.2 客观下线2.6.3 哨兵投票leader这段日志是在 Sentinel 的故障转移failover选举阶段三个 Sentinel 实例分别给自己投了票7e306443152983e1a064d99e4774455be261892e投给了自己60d432153554cfdcf9964d3b658e94a93c7d6c42投给了自己e579d34bdf549845cc935fb74218aeecb0e3d933投给了自己按理说应该会有投票过半来选出leader的现在这个没有选出leader的情况我也不知咋整但是也能实现子节点变为主节点主节点还能修改数据说明不是临时性的你说的情况其实挺典型Sentinel 故障转移失败没选出leader但某个从节点却“自己”变成了主节点这通常叫“脑裂”split-brain现象。现象解读Sentinel 之间无法达成共识导致没有选出新的主节点领导者leader但某些从节点自己判断主节点不可用自动升级为主节点这种自动晋升是 Redis 自身的保护机制不过默认 Redis 从节点不会自动升为主节点除非你启用了slave-serve-stale-data no并且客户端或者外部脚本主动切换这样就导致了集群中出现两个“主节点”造成数据不一致风险。没影响当前操作先搁置先~2.6.4 leader选择规则2.6.5 leader需要做啥事