redis集群(Sentinel)
问题
- Redis 主哨兵模式是如何保证高可用的
主要依赖主哨兵的发现故障和故障转移
概述
本文假设读者对redis 的主从复制已经进行了了解 。
Redis 主哨兵集群为Redis 提供了高可用,即高可用是猪哨兵模式的主要目的,这是宏观上Sentinel功能的完整列表
- Monitoring :监视实例的情况
- Notification : 通知
- Automatic failover : 当Master异常下线后,自动会通过选举
- Configuration provider : 提供配置信息。
注意事项
在配置哨兵模式下几件事需要注意 :
- 至少保证3台实例
- 由于Redis使用异步复制,因此Sentinel + Redis分布式系统不能保证在故障期间保留已确认的写入。
- 开启 Sentinel后,客户端也需要支持 Sentinel 模式
工作流程
分布式服务器布局
主哨兵的可以是如下布局

这是最简单的布局,Sentinel 依附在实例中,当实例 down 的话,那么 Sentinel 自然也会 down 掉,而图中的 quorum = 2 是什么意思呢,在后面章节再解释。二这种布局会出现分布式服务器“脑裂”问题,如下图

此时可以看到一台 replcation 成为了新的 master,而假如此刻客户端对 redis 进行写入那么数据将会丢失, redis.conf 中的两个参数可以设置
min-replicas-to-write 1
min-replicas-max-lag 10
使用以上配置,Redis实例在充当主实例时,如果无法写入至少1个副本,将停止接受写入。 由于复制是异步的,因此实际上无法写入意味着复制副本已断开连接,或者没有向我们发送异步确认超过指定的最大延迟秒数。
另外一种布局

或是

后面这两种的优势和缺点可见官网文档
流程
Sentinel 可以分为以下几个步骤
- 各个Sentinel认为 master 主观下线
- 多个 Sentinel 认为 master 客观下线
- 故障转移
检测主观下线状态
主观下线是什么意思呢?就是(站在Sentinel的角度)认为自己监听的 master 下线了,超过了某个心跳的时间没有回应。
检测客观下线状态
当Sentinel判定master 主观下线后,它就会去询问其他Sentinel是否他们也监控到master 下线了,当达到一定的数量,Sentinel 就会将服务器判定为客观下线,并对主服务器执行故障转移操作。而这个数量就是我们上面讲到的 quorum,上面的例子就是 :当询问到有包括自己有两台 Sentinel 监控到master 下线了,那么就判定主服务器客观下线。
选举 Snentinel
为什么要选举 Snentinel 呢?现在主服务器下线了,那么需要选举一台 Sentinel 来进行协调工作,使得故障转移得以进行。那么如何选举呢?选举的方法和 Raft 的方式一样,本文不再重复,参阅参考资料 。
故障转移
故障转移共分为下面几步
- 选出新的主服务器
- 修改从服务器的复制目标
- 将旧的主服务器变为从服务器
第一步,选举新的主服务器的标准肯定是谁拥有最新的记录最有资格充当主服务器了(主从复制,复制一半主挂了),而第二步也很好理解,既然旧的主服务器已经挂了,新的被选出来,自然要修改从服务器的复制目标,最后旧的服务器变成从服务器。
底层实现
参阅以下链接
- https://www.cnblogs.com/renpingsheng/p/9803838.html
我们也可以从上面的工作原理猜测,Sentinel 不仅要有连接 master和 replication的通信通道,还要有连接其他的Sentinel的通信通道,以便监控判定主服务器客观下线和其他功能。
实践部分
使用docker 搭建主从集群
实践部分参照以下链接,在此表示感谢!
- https://www.cnblogs.com/bixiaoyu/p/10745874.html
我们将要搭建是这个布局的分布式 redis集群

先搭建docker ip相关。
docker network create --subnet=172.60.0.0/16 mynetwork
搭建之前我们需要redis.conf 和 sentinel.conf 文件,获取方法可以去下载redis的config文件夹下拿到。
master 主服务器
然后执行
docker run -d -p 6900:6900 -v /home/docker_software/redis/redis.conf:/usr/local/etc/redis/redis.conf -v /home/docker_software/redis/data:/data -v /home/docker_software/redis/sentinel_master.conf:/usr/local/etc/redis/sentinel.conf --name redis-ip-m --net=mynetwork --ip 172.60.0.2 docker.io/redis redis-server /usr/local/etc/redis/redis.conf --appendonly yes
-d: 后台运行-p: 端口映射-v: 挂载目录和文件,上面用于redis.conf 和 sentinel.conf 放进容器内,而/data 则是数据目录,因为 docker 停止后数据会丢失,所以/data 目录挂载在宿主机器中redis-server: 启动的服务/usr/local/etc/redis/redis.conf: 启动的配置(由于配置了挂载文件所以执行的挂载文件)-ip: 指定ip地址--appendonly yes: 运行参数,表明进行持久化
replication1 从服务器
修改redis.conf ,在最后一行加上
slaveof 172.60.0.2 6900 ##主从复制
执行
docker run -d -p 6901:6901 -v /home/docker_software/redis/redis1.conf:/usr/local/etc/redis/redis.conf -v /home/docker_software/redis/data1:/data -v /home/docker_software/redis/sentinel_r.conf:/usr/local/etc/redis/sentinel.conf --name redis-ip-r1 --net=mynetwork --ip 172.60.0.3 docker.io/redis redis-server /usr/local/etc/redis/redis.conf --appendonly yes
另外一台从服务器也是同样的步骤,搭建完后是这样的 :
[root@localhost redis]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7bc085663022 docker.io/redis "docker-entrypoint..." 2 hours ago Up 2 hours 6379/tcp, 0.0.0.0:6902->6902/tcp redis-ip-r2
8eebf70c4a84 docker.io/redis "docker-entrypoint..." 2 hours ago Up 2 hours 6379/tcp, 0.0.0.0:6901->6901/tcp redis-ip-r1
28e0f66cbd40 docker.io/redis "docker-entrypoint..." 2 hours ago Up 2 hours 6379/tcp, 0.0.0.0:6900->6900/tcp redis-ip-m
共三台。
sentinel 监控
进入容器内,修改 sentinel.conf 文件,将
#sentinel myid b82a11362cfc53b1d8e552f04acada1d13946b11 注释掉 sentinel monitor mymaster 172.60.0.2 6900 2 logfile "/data/sentinel" #日志地址
注释掉因为其他两台从服务器的 sentinel.conf 也是指定这个id(搭建的时候复制了同一份 sentinel.conf),其他配置看conf文件解释。
然后
/usr/local/bin/redis-sentinel /usr/local/etc/redis/sentinel.conf
其他两台服务器也是这样的步骤启动,然后到我们的日志地址看看日志输出

可以看到另外两台 sentinel也启动了。
故障转移测试
我们使用
docker stop 主服务器容器
把主服务器停了,看一下日志有什么变化。

我们可以看到成功地把从服务器变为了新的主服务器,并将旧的主服务器变为从服务器,实验成功!
参考资料
- https://redis.io/topics/cluster-tutorial/
- https://www.cnblogs.com/renpingsheng/category/1317158.html
- https://www.cnblogs.com/fan-gx/p/11463400.html
- https://www.cnblogs.com/bixiaoyu/p/10745874.html(主从搭建,推荐一看)
redis集群(Sentinel)的更多相关文章
- Redis集群 - Sentinel与RAFT算法
引入 在主从模型中讲到 一旦Master宕机失效,需要手动将Slave角色提升为Master,否则这个子集群将不可用. 这个缺陷使得系统可用性大大降低.因此Redis专门提供了一个哨兵机制来实 ...
- redis集群sentinel哨兵模式的搭建与实际应用
参考资料:https://blog.csdn.net/men_wen/article/details/72724406 之前环境使用的keepalived+redis vip集群模式,现在我们服务切换 ...
- Redis集群~windows下搭建Sentinel环境及它对主从模式的实际意义
回到目录 关于redis-sentinel出现的原因 Redis集群的主从模式有个最大的弊端,就是当主master挂了之前,它的slave从服务器无法提升为主,而在redis-sentinel出现之后 ...
- redis 集群热备自动切换sentinel配置实战
---恢复内容开始--- Redis SentinelSentinel(哨兵)是用于监控redis集群中Master状态的工具,其已经被集成在redis2.4+的版本中一.Sentinel作用:1): ...
- Redis集群~StackExchange.redis连接Sentinel服务器并订阅相关事件(原创)
回到目录 对于redis-sentinel我在之前的文章中已经说过,它是一个仲裁者,当主master挂了后,它将在所有slave服务器中进行选举,选举的原则当然可以看它的官方文章,这与我们使用者没有什 ...
- sentinel搭建redis集群经验总结
一.protected-mode默认情况下,redis node和sentinel的protected-mode都是yes,在搭建集群时,若想从远程连接redis集群,需要将redis node和se ...
- (转)基于Redis Sentinel的Redis集群(主从&Sharding)高可用方案
转载自:http://warm-breeze.iteye.com/blog/2020413 本文主要介绍一种通过Jedis&Sentinel实现Redis集群高可用方案,该方案需要使用Jedi ...
- Redis集群_3.redis主从自动切换Sentinel(转)
Redis SentinelSentinel(哨兵)是用于监控redis集群中Master状态的工具,其已经被集成在redis2.4+的版本中 一.Sentinel作用:1):Master状态检测 2 ...
- 基于Redis Sentinel的Redis集群(主从Sharding)高可用方案(转)
本文主要介绍一种通过Jedis&Sentinel实现Redis集群高可用方案,该方案需要使用Jedis2.2.2及以上版本(强制),Redis2.8及以上版本(可选,Sentinel最早出现在 ...
- redis单点、redis主从、redis哨兵sentinel,redis集群cluster配置搭建与使用
目录 redis单点.redis主从.redis哨兵 sentinel,redis集群cluster配置搭建与使用 1 .redis 安装及配置 1.1 redis 单点 1.1.2 在命令窗口操作r ...
随机推荐
- 题解【AcWing91】最短Hamilton路径
题面 看到数据范围这么小,第一眼想到爆搜. 然而这样做的复杂度是 \(\mathcal{O}(n! \times n)\) 的,明显会 TLE. 于是考虑状压 DP. 我们设 \(dp_{i,j}\) ...
- 数据库SQL练习(一):数据查询
先创建以下3张基本表 1.学生信息表(Student): 2.课程表(Course): 3.成绩表(Score): 4. 将下列数据输入各个表中 建表SQL: CREATE DATABASE Stud ...
- MCPS & MIPS
MIPS:Million Instructions Per Second MCPS:Million Cycles Per Second MIPS = Total Instructions*Sampli ...
- c语言该怎么入门?C语言入门教程(非常详细)
C语言是一门面向过程的编译型语言,它的运行速度极快,仅次于汇编语言.C语言是计算机产业的核心语言,操作系统.硬件驱动.关键组件.数据库等都离不开C语言:不学习C语言,就不能了解计算机底层. 这套「C语 ...
- 笔记(tm_springboot)
1.@change="getFile($event)" 2.File imageFolder= new File(request.getServletContext().getRe ...
- Codeforces Round #600 (Div. 2) A. Single Push
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; int T,n ...
- 杭电oj1717——小数化分数(java实现)
question:小数化分数2 思路: /** * 这道题没有整数部分(有也无所谓,算小数部分,算完了分子分母按倍数加上就好),也就是说数组直接从a[2]开始后面是小数,我把这道题分为了三类: * * ...
- C++ 跨dll传递string类型参数执行出错问题
今天遇到一个问题,在一个dll工程中定义了一个返回值为string,参数为string的函数,然后在一个测试工程中调用,Release模式下一切正常Debug模式下整个函数的执行到return之前都毫 ...
- AE(ArcGIS Engine)的安装与配置(附加ArcGIS安装及所需安装包)
https://blog.csdn.net/qq_38281942/article/details/82534279
- Makefile文件(DE1-soc软件实验”hello_word")
DE1-soc软件实验”hello_word"中,hello_word此程序很好理解,那Makefile文件又如何理解呢? 所要完成的Makefile 文件描述了整个工程的编译.连接等规则. ...