Redis Sentinel 深度解析:构建高可用性 Redis 集群

2024-09-07 17:12

本文主要是介绍Redis Sentinel 深度解析:构建高可用性 Redis 集群,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Redis Sentinel 深度解析:构建高可用性 Redis 集群

  • 一 . 基本概念
    • 1.1 相关名词解释
    • 1.2 如何人工恢复主节点故障 ?
    • 1.3 哨兵自动恢复主节点故障
  • 二 . 哨兵的安装部署
    • 2.1 安装 docker 和 docker-compose
    • 2.2 搭建 Redis 的哨兵环境
      • 2.2.1 编排 Redis 的主从节点
      • 2.2.2 编排 redis-sentinel 节点
      • 2.2.3 启动容器
  • 三 . 哨兵节点的演示
    • 3.1 模拟主节点下线
    • 3.2 主从切换的具体流程
  • 四 . 小结

Hello , 大家好 , 这个专栏给大家带来的是 Redis 系列 ! 本篇文章给大家讲解的是 Redis 的集群. Redis 集群是一种提供自动分区的 Redis 数据库实现,它将数据自动分配到多个节点上。每个节点负责整个键值空间的一部分,从而允许数据库的扩展超越单个机器的内存限制。Redis 集群通过使用分片(sharding)技术来实现数据的分布式存储,同时提供一定程度的高可用性和容错能力。

在这里插入图片描述
本专栏旨在为初学者提供一个全面的 Redis 学习路径,从基础概念到实际应用,帮助读者快速掌握 Redis 的使用和管理技巧。通过本专栏的学习,能够构建坚实的 Redis 知识基础,并能够在实际学习以及工作中灵活运用 Redis 解决问题 .
专栏地址 : Redis 入门实践

一 . 基本概念

在 Redis 的主从复制中 , 存在一个关键的问题 : 如果主节点挂了 , 那整个系统读操作是可以继续进行的 , 但是写操作是执行不了的 . 那我们要想恢复这种情况 , 就需要人工来去进行维修 , 或者人工进行配置让其中一个从节点晋升为主节点 .

那能否通过自动化的手段来去解决主节点挂了的问题呢 ?

在 Redis 2.8 之后就提供了哨兵机制 (Sentinel) 来解决这个问题 .

1.1 相关名词解释

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

哨兵机制 , 是通过独立的进程来体现的 , 和之前学习的 redis-server 是不同的进程 , 哨兵节点不负责存储数据 , 只是对其他的 redis-server 进程起到监控的效果 .

在实际情况下 , 哨兵节点也是一组集合 (多个哨兵节点构成) , 防止单个哨兵节点挂了影响到整个系统的监控 .

1.2 如何人工恢复主节点故障 ?

1.3 哨兵自动恢复主节点故障

那 Redis 哨兵核心的功能就有这几点 :

  1. 监控 : 监控主节点和从节点的工作状态 , 并且能及时发现某个节点是否挂了
  2. 自动故障转移 : 如果主节点挂了 , 那哨兵就会自动选出一个新的从节点升级为主节点 , 保证整体依然可以进行读和写
  3. 通知 : 转移结束之后 , 就会通知客户端新的主节点

一般来说 , Redis 哨兵节点也是多个一起工作的 , 只有一个哨兵节点工作其实也是可以的 , 但是并不推荐

  1. 如果哨兵节点只有一个 , 他自身也是非常容易出现问题的 . 万一这个哨兵节点挂了 , 后续 Redis 节点挂了那就没有办法自动进行恢复了
  2. 出现误判的概率也比较高 : 网络传输非常容易出现抖动 / 延迟 / 丢包 , 一般来说都是短时间的异常 , 那如果只有一个哨兵节点 , 他就会认为该节点出现了问题 , 导致很容易出现误判 .

在分布式系统中 , 应该避免使用各种 “单点” , 也就是一定要多堆料 .

二 . 哨兵的安装部署

我们准备搭建出这样的结构

按理说 , 这六个节点 , 是需要部署在六个不同的服务器主机上的

那我们只有一个云服务器 , 就只能在一个云服务器上 , 完成这里的环境搭建 .

在实际工作中 , 把上述节点都放到一个服务器上 , 是没有任何意义的 .

由于这些节点比较多 , 相互之间容易产生冲突 . 如果直接部署 , 就需要手动修改很多配置 , 来去分别设置不同的端口号、不同的配置文件、不同的工作目录等 . 这种方式比较繁琐 , 也会和在不同主机上部署存在很大的差异 .

利用 docker 就可以有效的解决上述麻烦的问题 , docker 就相当于一个虚拟机 , 通过软件就可以在一台电脑上模拟出另外的一些硬件资源 (就相当于构造了另外一个虚拟的电脑) , 虚拟机他最大的问题就是比较吃配置 . 这个事情对于我们的云服务器来说压力非常大 .

相比之下 , docker 就能够解决这样的问题 , docker 就相当于一个轻量虚拟机 , 不仅起到了虚拟机这样的隔离环境的效果 , 也没有消耗很多的硬件资源 .

2.1 安装 docker 和 docker-compose

Docker 中的一个重要的概念 , 叫做容器 , 容器就可以看做是一个轻量级的虚拟机 .

那 docker-compose 的作用就是便于管理一系列的容器

后续我们会将安装 Docker 和 docker-compose 的方法补充到这里

2.2 搭建 Redis 的哨兵环境

我们使用 docker-compose 来进行容器的编排工作

容器的编排指的是我们目前涉及到多个 Redis server , 也有多个 Redis 哨兵节点 . 每一个 Redis server / 每一个哨兵节点都是作为一个单独的容器 .

那我们总共需要 6 个容器 , 每个容器单独配置也是比较麻烦的 , 所以我们需要 docker-compose 来帮助我们进行容器编排

利用 docker-compose 的方式 , 通过一个配置文件 , 把具体要创建哪些容器以及每个容器运行的各种参数描述清楚 , 后续通过一个简单的命令就能够批量的启动 / 停止这些容器了 .

docker-compose 使用 yml 这样的格式来去作为配置文件 .

那接下来我们就开始部署一下 docker-compose , 我们的需求是

  • 创建三个容器 , 作为 Redis 的数据节点 (一主二从)
  • 创建三个容器 , 作为 Redis 的哨兵节点

那我们分别创建各自的 yml 文件来去配置

其实也可以用一个 yml 文件直接启动 6 个容器 , 但是如果这 6 个容器同时启动 , 就有可能出现这种情况 :

如果哨兵节点先启动完成 , 数据节点后启动完成 , 那哨兵节点就会认为是数据节点挂了 , 导致一些日志打印不符合我们的预期

2.2.1 编排 Redis 的主从节点

首先 , 我们先创建一个 redis 目录 , 然后进入该目录

mkdir redis
cd redis

然后创建两个文件夹

  • redis-data : 存放数据节点
  • redis-sentinel : 存放哨兵节点
mkdir redis-data
mkdir redis-sentinel

然后进入到 redis-data 目录中 , 用 vim 编辑器去编辑 docker-compose.yml 这个文件

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

我们也来看一下这个配置文件的含义

此时我们就可以启动该配置了 , 使用 docker-compose up -d 命令

那我们还可以通过 netstat -anp | grep 6379 … 6380 … 6381 就可以查看一下端口是否被占用 , 如果被占用就代表容器已经启动

接下来我们可以启动一下客户端 , 使用 redis-cli -p 6379 命令 , 就连接到了容器当中的 Redis 了

我们还可以通过 docker-compose logs 来去查看这些容器产生的日志

2.2.2 编排 redis-sentinel 节点

我们进入到 redis-sentinel 目录 , 然后用 vim 打开 docker-compose.yml 文件

cd /root/redis/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

我们还是来看一下 redis-sentinel 配置文件的含义

那我们还需要创建出 sentinel1、sentinel2、sentinel3 这三个配置文件 . 初始情况下 , 这三个配置内容文件可以相同 , 当容器启动之后就会对配置文件进行自适应调整 . 下面就是 sentinel.conf 配置文件的内容

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

那接下来我们就需要在 /root/redis/redis-sentinel 路径下创建出 sentinel1、sentinel2、sentinel3 这三个配置文件

cd /root/redis/redis-sentinel
vim sentinel1.conf
cp sentinel1.conf sentinel2.conf
cp sentinel1.conf sentinel3.conf

2.2.3 启动容器

使用命令 docker-compose up -d 命令按照后台进程的方式启动 , 稍等片刻之后三个哨兵节点就已经启动

-d 参数指的就是按照后台进程的方式来启动

然后我们通过 docker-compose logs 命令来去查看启动日志

我们发现日志中有一些错误 , 他的意思是我们的配置文件中有错误 , 在第三行位置

也就是说 , 哨兵节点不认识 redis-master . redis-master 此处就相当于一个域名 , Docker 就会自动进行域名解析 , 但是现在解析失败了 .

失败的原因主要是 docker-compose 一下子启动了 N 个容器 , 此时这 N 个容器都处于同一个局域网中 , 那这 N 个局域网就可以进行互相访问 . 但是我们目前三个 redis-server 节点是在一个局域网 , 三个哨兵节点是在另一个局域网 , 默认情况下不同局域网之间是不互通的 .

解决方案就是将这两次不同的 docker-compose 操作对应的容器放到同一个局域网中 , 使用 docker network ls 列出当前 docker 中的局域网 , 然后根据列出来的数据再去进行下一步的配置

我们先启动了三个 redis-server 节点 , 就相当于自动创建了第一个局域网 . 然后再启动三个哨兵节点 , 就又创建了第二个局域网 .

我们要做的是之后再去执行 docker-compose 命令的时候 , 不自动创建新的局域网 , 直接加入到已有的局域网 .

解决的方法就是在我们 redis-sentinel 节点的配置文件中 , 在最后面添加 network 配置

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

我们重新打开 redis-sentinel 文件夹下的配置文件进行粘贴

cd /root/redis/redis-sentinel
vim docker-compose.yml

然后配置完毕就可以重新启动容器了 , 先使用 docker-compose down 命令停止掉当前 docker 服务 , 然后重新执行 docker-compose up -d 命令

然后我们重新来看一下启动日志 , 使用 docker-compose logs 命令 , 此时日志也就正常打印了

三 . 哨兵节点的演示

哨兵节点存在的意义就是能够在 Redis 主从结构出现问题的时候 (比如 : 主节点挂了) , 此时哨兵节点就能够自动的帮我们重新选举出一个新的节点来去代替之前的主节点 , 保证整个 Redis 是可用状态 .

我们可以先看一下目前存在的节点信息 , 使用 docker ps -a 命令

接下来 , 我们就可以模拟一下主节点挂了的情况

3.1 模拟主节点下线

我们使用 docker stop 容器名称来去停止主节点

当我们主节点挂了的时候 , 哨兵节点此时就已经开始工作了 , 我们可以观察一下哨兵节点的日志

cd /root/redis/redis-sentinel
docker-compose logs

我们重点观察一个哨兵节点的日志 , 我们选择 redis-sentinel-3 这个哨兵节点

此时 , 主节点已经恢复 , 我们尝试连接一下 Redis 客户端

那 6379 服务已经下线 , 6380 升级成了新的主节点 , 那 6381 应该就是从节点 , 只不过父节点变成了 6380

那此时 , 如果我们将下线的主节点重新启动 , 会发生什么 ?

使用命令 docker start redis-master 命令

我们可以看到 , 之前的主节点虽然正常启动了 , 但是他的身份从主节点变成了从节点 , 挂在了新的主节点的下面

3.2 主从切换的具体流程

哨兵节点重新选取主节点的流程

四 . 小结

  1. 哨兵节点不能只有一个 , 否则单个哨兵节点挂了就会影响系统的可用性 .
  2. 哨兵节点最好是奇数个 , 方便选举 leader , 得票更容易超过半数 .
  3. 哨兵节点不负责存储数据 , 只负责监控主从节点 , 真正存储和读取数据的是 Redis 的主从节点 , 因此哨兵节点就可以使用一些配置不高的机器来部署 .
  4. “哨兵+主从复制” 解决的问题是提高可用性 , 并不能解决数据极端情况下写丢失的问题 .
  5. “哨兵+主从复制” 并不能提高数据的存储容量 . 使用 Redis 中的集群 , 就是解决存储容量问题的有效方案 , 敬请期待 .

对于 Redis 中的哨兵机制 , 我们就分享到这里 , 如果对你有帮助的话 , 请一键三连 , 谢谢~
在这里插入图片描述

这篇关于Redis Sentinel 深度解析:构建高可用性 Redis 集群的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1145650

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

HDFS—集群扩容及缩容

白名单:表示在白名单的主机IP地址可以,用来存储数据。 配置白名单步骤如下: 1)在NameNode节点的/opt/module/hadoop-3.1.4/etc/hadoop目录下分别创建whitelist 和blacklist文件 (1)创建白名单 [lytfly@hadoop102 hadoop]$ vim whitelist 在whitelist中添加如下主机名称,假如集群正常工作的节

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

搭建Kafka+zookeeper集群调度

前言 硬件环境 172.18.0.5        kafkazk1        Kafka+zookeeper                Kafka Broker集群 172.18.0.6        kafkazk2        Kafka+zookeeper                Kafka Broker集群 172.18.0.7        kafkazk3

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG