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

Redis ①④-哨兵

在这里插入图片描述

Redis 哨兵

在主从复制模式中,如果主节点挂掉了,需要手动把读写请求切换到从节点,这就需要人工干预,费时费力,甚至可能会出错.

Redis 哨兵(Sentinel)就是为了解决这一问题而产生的.

Redis 哨兵(Sentinel)相关名词解释:

名词逻辑结构物理结构
主节点Redis 主服务一个独立的 redis-server 进程
从节点Redis 从服务一个独立的 redis-server 进程
Redis 数据节点主从节点主节点和从节点的进程
哨兵节点监控 Redis 数据节点的节点一个独立的 redis-sentinel 进程
哨兵节点合集若干哨兵结点的抽象组合若干 redis-sentinel 进程
Redis 哨兵(Sentinel)Redis 提供的高可用方案哨兵节点集合和 Redis 主从节点
应用方泛指多个客户端一个或多个连接 Redis 的进程

Redis Sentinel 架构图在这里插入图片描述

sentinel 往往由多个节点,如果只设置一个的话,如果该节点挂掉了,整个服务就不可用了.sentinel 节点的个数一般设置为奇数,3 个节点较为推荐.(在分布式系统,要避免 “单点”,“冗余” 反而不是一件坏事)

Redis Sentinel 的主要功能:

  • 监控:sentinel 会不断地检查主节点和从节点是否正常工作.
  • 自动故障转移:当主节点出现故障时,会自动转移到其他从节点.
  • 通知:当故障发生时,sentinel 可以通过 API 发送通知给客户端或者其他哨兵节点.

自动故障转移过程:

  1. 主节点故障,从节点同步连接中断,主从复制停止.
  2. 某个哨兵节点通过定期监控发现主节点故障,为了确保不是自己误判,该哨兵节点需要和其他哨兵节点进行确认,达成共识后,才真正认定该主节点故障.
  3. 认定确实是主节点故障后,哨兵节点之间通过 Raft 算法选举出一个 Leader,由 Leader 负责将失效主节点的从节点升为新主节点.
  4. 哨兵 Leader 开始执行故障转移,从失效主节点的从节点中选择一个,将其升级为新主节点,让其他从节点同步到新主节点,通知应用层转移到新主节点.

通过 Docker 部署 Redis 哨兵

安装 Docker 和 Docker Compose.

停止之前所有的 Redis 服务器

使用 Docker 拉取 Redis 镜像

docker pull redis:5.0.9

编排主从节点

创建 docker-compose.yml 文件

mkdir redis
cd redis
mkdir redis-data
cd redis-data
vim docker-compose.yml
version: '3.7'
services:master:image: 'redis:5.0.9'container_name: redis-masterrestart: alwayscommand: redis-server --appendonly yesports:- 6379:6379slave1:image: 'redis:5.0.9'container_name: redis-slave1restart: alwayscommand: redis-server --appendonly yes --slaveof redis-master 6379ports:- 6380:6379slave2:image: 'redis:5.0.9'container_name: redis-slave2restart: alwayscommand: redis-server --appendonly yes --slaveof redis-master 6379ports:- 6381:6379

启动所有容器

# 在 /redis/redis-data 目录下执行
docker-compose up -d# 查看启动日志
docker-compose logs# 停止所有容器
docker-compose down

验证是否成功

redis-cli -p 6379
info replicationredis-cli -p 6380
info replicationredis-cli -p 6381

编排哨兵节点

创建 docker-compose.yml 文件

cd ..
mkdir redis-sentinel
cd redis-sentinel
vim docker-compose.yml
version: '3.7'
services:sentinel1:image: 'redis:5.0.9'container_name: redis-sentinel-1restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel1.conf:/etc/redis/sentinel.confports:- 26379:26379sentinel2:image: 'redis:5.0.9'container_name: redis-sentinel-2restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel2.conf:/etc/redis/sentinel.confports:- 26380:26379sentinel3:image: 'redis:5.0.9'container_name: redis-sentinel-3restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel3.conf:/etc/redis/sentinel.confports:- 26381:26379
networks:default:external:name: redis-data_default

创建 sentinel1.confsentinel2.confsentinel3.conf 文件,内容保持一致即可:

bind 0.0.0.0
port 26379
sentinel monitor redis-master redis-master 6379 2
sentinel down-after-milliseconds redis-master 1000

启动所有容器

# 在 /redis/redis-sentinel 目录下执行
docker-compose up -d# 查看启动日志
docker-compose logs

如果发现启动失败,且报如下错误:

redis-sentinel-3 | *** FATAL CONFIG FILE ERROR (Redis 8.0.0) ***
redis-sentinel-3 | Reading the configuration file,at line 3
redis-sentinel-3 | >>> 'sentinel monitor redis-master redis-master 6379 2'
redis-sentinel-3 | Can't resolve instance hostname.

这通常是主从节点和哨兵节点不在同一局域网,导致 redis-master 不能被正确解析到 IP 地址.

解决方法:

  • 修改 /redis/redis-sentinel/docker-compose.yml
# 增加以下内容
networks:default:external:name: redis-data_default

网络的 name 可能不同,需要根据实际情况修改,通过 docker network ls 查看.

docker network ls
NETWORK ID     NAME                 DRIVER    SCOPE
04c0dbe75582   bridge               bridge    local
2873d9806bb3   host                 host      local
555daeff6b48   none                 null      local
6ec1a2f23d36   redis-data_default   bridge    local

重新启动所有容器

docker-compose downdocker-compose up -d

验证是否成功

docker ps -a

测试主节点故障转移

停止主节点

docker stop redis-master

等待 10 秒后,查看哨兵节点日志,可以看到有以下几条消息:

# +sdown master redis-master 172.19.0.3 6379
# +new-epoch 1
# +vote-for-leader d2b17359b64cbab6cd1af623ddf717d52eab48ba 1
# +odown master redis-master 172.19.0.3 6379 #quorum 3/2
# Next failover delay: I will not start a failover before Mon May 12 12:17:10 2025
# +config-update-from sentinel d2b17359b64cbab6cd1af623ddf717d52eab48ba 172.19.0.7 26379 @ redis-master 172.19.0.3 6379
# +switch-master redis-master 172.19.0.3 6379 172.19.0.2 6379
* +slave slave 172.19.0.4:6379 172.19.0.4 6379 @ redis-master 172.19.0.2 6379
* +slave slave 172.19.0.3:6379 172.19.0.3 6379 @ redis-master 172.19.0.2 6379
# +sdown slave 172.19.0.3:6379 172.19.0.3 6379 @ redis-master 172.19.0.2 6379
# -sdown slave 172.19.0.3:6379 172.19.0.3 6379 @ redis-master 172.19.0.2 6379
  • sdown:该哨兵节点主观(subjective)检测到主节点下线.
  • odown:#quorum 3/2:三个哨兵都认同主节点下线(超过设置的半数以上),所以是客观(objective)认为主节点下线,一般来说就是真的主节点挂了.
  • +new-epoch 1:哨兵节点开始新的一轮投票,选举出新的领导者.
  • +vote-for-leader d2###ba 1:投票给 id 为 d2###ba 的哨兵节点,票数为 1.(一般会率先投给自己一票,但是只能投一票).通过观察另外两个哨兵节点,发现它们投给了该节点,所以该节点获得半数以上的票数,称为 Leader,由该节点负责故障转移.
  • +config-update-from sentinel d2***ba 172.19.0.7 26379 @ redis-master 172.19.0.3 6379:通知其他哨兵节点,自己已经成为 Leader,它来开始进行 redis-master 的故障转移.
  • +switch-master redis-master 172.19.0.3 6379 172.19.0.2 6379:将失效主节点的从节点 172.19.0.3 升级为新主节点.

主节点故障全过程

  1. 主观下线: 哨兵节点通过心跳包,判定 redis 服务器是否正常工作,如果心跳包没有如约而至,则说明 redis 服务器故障.

  2. 客观下线: 多个哨兵节点都认为该节点故障了(达到法定票数).

  3. 选举 Leader: 这些哨兵节点选举出一个 Leader,由 Leader 负责故障转移.

  4. 故障转移: Leader 选取一个从节点,将其升级为新主节点,其他从节点同步到新主节点.

一般通过以下参数选举:

  • 优先级:每个 Redis 数据节点,都会在配置文件中,有一个优先级的设置:slave-priority,优先级越高的从节点,就会胜出.
  • offset:最大的 offset 值,就胜出.
  • runid:每个 redis 节点启动时随即生成一串数字,哪个大选哪个.

注意事项

  • 哨兵节点不能只有一个.否则哨兵节点挂了也会影响系统可用性.
  • 哨兵节点最好是奇数个.方便选举 Leader,得票更容易超过半数.
  • 哨兵节点不负责存储数据.仍然是 Redis 主从节点负责存储.
  • 哨兵 + 主从复制解决的问题是 “提高可用性”,不能解决 “数据极端情况下写丢失” 的问题.
    riority,优先级越高的从节点,就会胜出.
  • offset:最大的 offset 值,就胜出.
  • runid:每个 redis 节点启动时随即生成一串数字,哪个大选哪个.

注意事项

  • 哨兵节点不能只有一个.否则哨兵节点挂了也会影响系统可用性.
  • 哨兵节点最好是奇数个.方便选举 Leader,得票更容易超过半数.
  • 哨兵节点不负责存储数据.仍然是 Redis 主从节点负责存储.
  • 哨兵 + 主从复制解决的问题是 “提高可用性”,不能解决 “数据极端情况下写丢失” 的问题.
  • 哨兵 + 主从复制不能提高数据的存储容量.当我们需要存的数据接近或者超过机器的物理内存,这样的结构就难以胜任了.
http://www.lryc.cn/news/576341.html

相关文章:

  • Ubuntu20.04离线安装Realtek b852无线网卡驱动
  • HTML表格中<tfoot>标签用法详解
  • OD 算法题 B卷【计算误码率】
  • python解释器 与 pip脚本常遇到的问题汇总
  • 2025年健康医疗大数据开放共享:现状、挑战与未来发展
  • 掌握 MySQL 的基石:全面解读数据类型及其影响
  • ReasonGraph 大模型推理过程可视化开源工具使用探索,大模型幻觉可视化研究
  • zookeeper Curator(1):认识zookeeper和操作命令
  • [论文阅读] 软件工程 | 微前端在电商领域的实践:一项案例研究的深度解析
  • React 第六十六节Router中 StaticRouter使用详解及注意事项
  • 前端React和Vue框架的区别
  • 深入理解C#委托操作:添加、移除与调用全解析
  • 网络 : 传输层【UDP协议】
  • Linux-读者写者问题
  • STM32F103C8T6参数说明
  • Android4的InputReader
  • 一款支持多日志器、多级别、多落地方式的同异步日志系统
  • 搭建Flink分布式集群
  • 零知开源——基于STM32F407VET6零知增强板的四路独立计时器
  • 配置阿里云OSS实现https访问
  • 解决flash-attn安装报错的问题
  • Java-对象的字符串表示
  • Day45 Tensorboard使用介绍
  • 计算机操作系统(十七)内存管理
  • 关于上位机的热更新
  • 暑假复习篇之运算与逻辑
  • C#数据流处理:深入解析System.IO.Pipelines的奥秘
  • 数据结构与算法 --- 双向链表
  • 鸿蒙 Scroll 组件深度解析:丝滑滚动交互全场景实现
  • Python 数据分析与可视化 Day 10 - 数据合并与连接