本文主要是介绍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 哨兵核心的功能就有这几点 :
- 监控 : 监控主节点和从节点的工作状态 , 并且能及时发现某个节点是否挂了
- 自动故障转移 : 如果主节点挂了 , 那哨兵就会自动选出一个新的从节点升级为主节点 , 保证整体依然可以进行读和写
- 通知 : 转移结束之后 , 就会通知客户端新的主节点
一般来说 , Redis 哨兵节点也是多个一起工作的 , 只有一个哨兵节点工作其实也是可以的 , 但是并不推荐
- 如果哨兵节点只有一个 , 他自身也是非常容易出现问题的 . 万一这个哨兵节点挂了 , 后续 Redis 节点挂了那就没有办法自动进行恢复了
- 出现误判的概率也比较高 : 网络传输非常容易出现抖动 / 延迟 / 丢包 , 一般来说都是短时间的异常 , 那如果只有一个哨兵节点 , 他就会认为该节点出现了问题 , 导致很容易出现误判 .
在分布式系统中 , 应该避免使用各种 “单点” , 也就是一定要多堆料 .
二 . 哨兵的安装部署
我们准备搭建出这样的结构
按理说 , 这六个节点 , 是需要部署在六个不同的服务器主机上的
那我们只有一个云服务器 , 就只能在一个云服务器上 , 完成这里的环境搭建 .
在实际工作中 , 把上述节点都放到一个服务器上 , 是没有任何意义的 .
由于这些节点比较多 , 相互之间容易产生冲突 . 如果直接部署 , 就需要手动修改很多配置 , 来去分别设置不同的端口号、不同的配置文件、不同的工作目录等 . 这种方式比较繁琐 , 也会和在不同主机上部署存在很大的差异 .
利用 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 主从切换的具体流程
哨兵节点重新选取主节点的流程
四 . 小结
- 哨兵节点不能只有一个 , 否则单个哨兵节点挂了就会影响系统的可用性 .
- 哨兵节点最好是奇数个 , 方便选举 leader , 得票更容易超过半数 .
- 哨兵节点不负责存储数据 , 只负责监控主从节点 , 真正存储和读取数据的是 Redis 的主从节点 , 因此哨兵节点就可以使用一些配置不高的机器来部署 .
- “哨兵+主从复制” 解决的问题是提高可用性 , 并不能解决数据极端情况下写丢失的问题 .
- “哨兵+主从复制” 并不能提高数据的存储容量 . 使用 Redis 中的集群 , 就是解决存储容量问题的有效方案 , 敬请期待 .
对于 Redis 中的哨兵机制 , 我们就分享到这里 , 如果对你有帮助的话 , 请一键三连 , 谢谢~
这篇关于Redis Sentinel 深度解析:构建高可用性 Redis 集群的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!