Redis——哨兵模式与Zookeeper选举的异同点
摘要
当我们使用主从复制出现的问题:手动故障转移:写能力和存储能力受限:主从复制 -master 宕机故障处理。
主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。

哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
哨兵主要有两个作用
-
通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
-
当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。
然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。
哨兵模式(raft)与Zookeeper模式(zab)选主的总结
- Redis中的Sentinel选主相对来说更简单,因为不涉及事务状态的一致性
- Sentinel选主是基于raft协议,Zookeeper则基于Zab协议
- 二者都是收到半数的选票就选举成功
- Sentinel投票发消息主要内容是Sentinel id和配置纪元,Zookeeper则是 zxid和 sid
- Sentinel谁先来找他投票他就投谁,Zookeeper中则是要细细检查比较一番,检查内容包括epoch和节点状态,检查完毕后再跟自己的投票进行pk,进而看需不需要更新自己的投票,若是需要,则自己的投票也要广播出去
故障切换(failover)的过程。
假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票(与Zookeeper的过半机制有什么不同 ),投票的结果由一个哨兵发起,进行failover操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。这样对于客户端而言,一切都是透明的。
架构说明

- 多个sentinel 发现并确认master有问题。
- 选举出一个sentinel作为领导(怎么选举?)
- 选出一个slave作为master
- 通知其余的slave成为新的master的slave
- 通知客户端主从变化
- 等待老的master复活成新的master的slave
领导者选举
-
只需要一个sentinel节点完成故障转移
-
通过sentinel is - master -down -by-addr 命令都希望成为领导者
- -1. 每个主观下线都Sentitle 节点向其他Sentinel节点发送命令,要求将它设置为领导者
- -2. 收到命令对Sentinel节点如果没有同一通过其他Sentinel节点发送的命令,那么就将同一该请求,否则拒绝
- -3. 如果该Sentinel节点发现直接的票数已经超过Sentinel集合半数且超过quorum,那么它将成为领导者
- -4. 如果此过程由多个Sentinel节点成为领导者,那么将来等待一段时间重新进行选举
需要说明的问题
- 尽可能在不同物理机上和同一个网络部署Redis sentinel的所有节点
- Redis sentinel中的sentinel节点个数应该大于等于3且最好是奇数。(节点数多可以保证高可用)
- Redis sentinel中的数据节点和普通数据节点没有区别。每个sentinel节点在本质上还是一个Redis实例,只不过和Redis数据节点不同的是,其主要作用是监控Redis数据节点
- 客户端初始化时连接的是sentinel节点集合,不再是具体的Redis节点,但sentinel只是配置中心不是代理。
哨兵模式与Zookeeper选举的异同点
zk 选举
假设有两个server
(1) 发起投票
每个Server发出一个投票投给自己。由于是初始情况,Server1和Server2都会将自己作为Leader服务器来进行投票,每次投票会包含所推举的服务器的myid和ZXID,使用(myid, ZXID)来表示,此时Server1的投票为(1, 0),Server2的投票为(2, 0),然后各自将这个投票发给集群中其他机器。
(2) 接受投票
来自各个服务器的投票。集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票(通过logicalclock确定是否轮次比当前大)、是否来自LOOKING状态的服务器。
(3) 处理投票。
轮次比较:
- 如果轮次比当前大,则清空本地投票箱recvset,并将自己和收到的投票PK,谁大投谁,并广播。
- 如果轮次跟当前一样,则比较本地投票箱里产生的leader和接受到的投票信息,谁大投谁,如果更新了就广播。
- 如果轮次比当前小,则忽略
选票PK:
1、优先检查ZXID。ZXID比较大的服务器胜出。
2、如果ZXID相同,那么就比较myid。myid较大的服务器胜出。
例如:对于Server1而言,它的投票是(1, 0),接收Server2的投票为(2, 0),首先会比较两者的ZXID,均为0,再比较myid,此时Server2的myid最大,于是更新自己的投票为(2, 0),然后重新投票,对于Server2而言,其无须更新自己的投票,只是再次向集群中所有机器发出上一次投票信息即可。
(4) 统计投票。
每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,对于Server1、Server2而言,都统计出集群中已经有两台机器接受了(2, 0)的投票信息,此时便认为已经选出了Leader。
(5) 改变服务器状态。
一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING。
redis 选举
如果需要从redis集群选举一个节点为主节点,首先需要从Sentinel集群中选举一个Sentinel节点作为Leader。
每一个Sentinel节点都可以成为Leader,当一个Sentinel节点确认redis集群的主节点主观下线后,会请求其他Sentinel节点要求将自己选举为Leader。被请求的Sentinel节点如果没有同意过其他Sentinel节点的选举请求,则同意该请求(选举票数+1),否则不同意。
如果一个Sentinel节点获得的选举票数达到Leader最低票数(quorum和Sentinel节点数/2+1的最大值),则该Sentinel节点选举为Leader;否则重新进行选举。
当Sentinel集群选举出Sentinel Leader后,由Sentinel Leader从redis从节点中选择一个redis节点作为主节点:
- 过滤故障的节点
- 选择优先级slave-priority最大的从节点作为主节点,如不存在则继续
- 选择复制偏移量(数据写入量的字节,记录写了多少数据。主服务器会把偏移量同步给从服务器,当主从的偏移量一致,则数据是完全同步)最大的从节点作为主节点,如不存在则继续
- 选择runid(redis每次启动的时候生成随机的runid作为redis的标识)最小的从节点作为主节点
Redis选举领头Sentinel(raft算法)
Sentinel是Redis实现高可用的保证。Sentinel系统作用就是监视Redis服务器集群,它可以不停的获得redis集群状态,当一个主节点挂了,故障转移操作会在从节点中选出一个新的主节点,这里故障转移就是由Sentinel来主导完成的。不要把Sentinel想的太复杂,它其实就是一个特殊工作模式的Redis服务器而已,Redis是集群部署的,这里的Sentinel也是要集群部署的,要是非单点部署,你的Sentinel挂了,此时的Redis集群就GG了。接着上边说,当主服务器节点挂了,Sentinel系统就会选出一个领头的Sentinel来完成故障转移工作。选举规则如下: - 监视这个挂了的主节点的所有Sentinel都有被选举为领头的资格
- 每进行一次选举,不论是否成功,配置纪元+1,配置纪元就是个计数器
- 每个Sentinel在每个配置纪元中有且仅有一次选举机会,一旦选好了该节点认为的主节点,在这个纪元内,不可以再更改
- 每个发现服务器挂了的Sentinel都会配置纪元+1并投自己一票,接着发消息要求其他Sentinel设置自己为领头人1,每个Sentinel都想成为领头的
- 每个Sentinel会将最先发来请求领头的节点设为自己的领头节点并发送回复,谁先来我选谁
- 当源Sentinel收到回复,并且回复中的配置纪元和自己的一致且领头Id是自己的Sentinel Id时,表明目标Sentinel已经将自己设为领头
- 在一个配置纪元内,当某个Sentinel收到半数以上的同意回复时,它就是领头的了
- 如果在给定时间内,没有被成功选举的Sentinel,那么过段时间发起新的选举
选举领头Sentinel的过程和规则大概就如上所述,需要注意的是只有集群出现节点挂了才需要选举出领头Sentinel,平时每个Sentinel还是平等身份~
Zookeeper选举
Zookeeper是一个很强的分布式数据一致性解决方案,比如dubbo中的注册中心就使用的Zookeeper。当然,这也是集群部署的,但是它没有采用传统的Master/Slave结构,而是引入了Leader、Follwer和Observer。Leader和Follower类似于Master/Slave,新增的Observer作用仅仅只是增加集群的读性能,它不参与Leader的选举。
节点的状态有以下几种:
- LOOKING: 节点正处于选主状态,不对外提供服务,直至选主结束;
- FOLLOWING: 作为系统的从节点,接受主节点的更新并写入本地日志;
- LEADING: 作为系统主节点,接受客户端更新,写入本地日志并复制到从节点
Zookeeper的状态同步是基于Zab协议实现的,Zab协议有两种模式,它们分别是崩溃恢复(选主)和消息广播(同步)。当服务启动或者在Leader崩溃后,Zab就进入了恢复模式,当Leader被选举出来,且超过一半机器完成了和 leader的状态同步以后,恢复模式就结束了。
首先明确几个概念: - Sid:服务器id;
- Zxid:服务器的事务id,数据越新,zxid越大;zxid的高32位是epoch,低32位是zpoch内的自增id,由0开始。每次选出新的Leader,epoch会递增,同时zxid的低32位清0。
整个选主流程如下
- 状态变更。服务器启动的时候每个server的状态时Looking,如果是leader挂掉后进入选举,那么余下的非Observer的Server就会将自己的服务器状态变更为Looking,然后开始进入Leader的选举状态;
- 发起投票。每个server会产生一个(sid,zxid)的投票,系统初始化的时候zxid都是0,如果是运行期间,每个server的zxid可能都不同,这取决于最后一次更新的数据。将投票发送给集群中的所有机器;
- 接收并检查投票。server收到投票后,会先检查是否是本轮投票,是否来自looking状态的server;
- 处理投票。对自己的投票和接收到的投票进行PK:
先检查zxid,较大的优先为leader;如果zxid一样,sid较大的为leader;根据PK结果更新自己的投票,再次发送自己的投票;
- 统计投票。每次投票后,服务器统计投票信息,如果有过半机器接收到相同的投票,那么leader产生,如果否,那么进行下一轮投票;
- 改变server状态。一旦确定了Leader,server会更新自己的状态为Following或者是Leading。选举结束。
我们要保证选主完成后,原来的主节点已经提交的事务继续完成提交;原主节点只是提出而没提交的事务要抛弃。这也是为什么倾向于选zxid最大的从节点为主节点,因为它上边的事务最新,最与原主节点保持一致。
哨兵模式(raft)与Zookeeper模式(zab)选主的总结
- Redis中的Sentinel选主相对来说更简单,因为不涉及事务状态的一致性
- Sentinel选主是基于raft协议,Zookeeper则基于Zab协议
- 二者都是收到半数的选票就选举成功
- Sentinel投票发消息主要内容是Sentinel id和配置纪元,Zookeeper则是 zxid和 sid
- Sentinel谁先来找他投票他就投谁,Zookeeper中则是要细细检查比较一番,检查内容包括epoch和节点状态,检查完毕后再跟自己的投票进行pk,进而看需不需要更新自己的投票,若是需要,则自己的投票也要广播出去
相关文章:
Redis——哨兵模式与Zookeeper选举的异同点
摘要 当我们使用主从复制出现的问题:手动故障转移:写能力和存储能力受限:主从复制 -master 宕机故障处理。 主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干…...
基于 Center 的 3D 目标检测和跟踪
论文地址:https://arxiv.org/abs/2006.11275 论文代码:https://github.com/tianweiy/CenterPoint 3D 目标通常表示为点云中的 3D Boxes。 CenterPoint 在第一阶段,使用关键点检测器检测对象的中心,然后回归到其他属性࿰…...
华锐技术何志东:证券核心交易系统分布式改造将迎来规模化落地阶段
近年来,数字化转型成为证券业发展的下一战略高地,根据 2021 年证券业协会专项调查结果显示,71% 的券商将数字化转型列为公司战略任务。 在落地数字化转型战略过程中,证券业核心交易系统面临着不少挑战。构建新一代分布式核心交易…...
数据结构 -- ArrayList与LinkedList的区别
一、二者的相同点 1,它们都是继承自List接口。 二、二者的区别 1,数据结构:ArrayList是(Array动态数组)的数据结构;而LinkedList是(Link双向链表)的数据结构。ArrayList 自由性较…...
豪车托运为什么选小板
小板运输是一种适用于豪车客户的高效运输方式。它提供了快速、安全、便捷的服务,并且相对经济实惠。以下是关于小板运输的时效和价格的介绍: 时效:小板运输通常能够在短时间内完成车辆的运输。具体时效取决于起点和目的地之间的距离ÿ…...
【base64加密】js/ts的基础加密
base64的字符串简单加密,主用于网页缓存数据的加密。 适用于常规html、小游戏(egret、cocos、laya)等 原文参考:JS基于base64编码加密解密文本和图片(修订)_js base64加密-CSDN博客 测试:JS实…...
基于python的app程式开发
安装的库文件: 运行代码: # -*- coding:utf-8 -*- from kivy.app import App class HelloApp(App):pass if __name__ __main__:HelloApp().run() 结果画面:...
Spring Event学习
Spring Event学习 观察者模式是一种行为设计模式,它定义了对象之间的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。在这个模式中,改变状态的对象被称为主题,依赖的对象被称为观…...
UE4 HLSL学习笔记
在Custom配置对应ush文件路径 在HLSL中写入对应代码 Custom里面增加两个Input,名字必须和ush文件内的未知变量名字一样 然后就对应输出对应效果的颜色 这就是简单的加法运算 减法同理: 乘法除法同理 HLSL取最小值 HLSL取最大值 绝对值: 取余…...
报文的路由过程
路由转发过程 记住路由转发过程结论:报文ip是不变,mac改变。 mac地址在同一个广播域传输过程中是不变的;在跨越广播域的时候会发生改变的;而IP地址在传输过程中是不会改变的(除NAT的时候)。 ip地址本质上是…...
【CPP】类和对象
1- Classes and Objects Structures A struct in C is a type consisting of a sequence of data membersSome functions/Statements are needed to operate the data members of an object of a struct type 不不小心操作错误,不小心越界 Classes You should b…...
【多线程面试题二十】、 如何实现互斥锁(mutex)?
文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官:如何实现互斥锁…...
hypercube背景设置为白色,绘制高光谱3D立方体
import scipy pip install wxpython PyOpenGL和Spectral需要本地安装 可参考链接https://blog.csdn.net/qq_43204333/article/details/119837870 参考:https://blog.csdn.net/Tiandailan/article/details/132719745?spm1001.2014.3001.5506Mouse Functions:left-cl…...
Visual Studio(VS)C++项目 管理第三方依赖库和目录设置
发现很多程序员存在这种做法:把项目依赖的第三方库的lib和dll放在项目目录下,或者复制到输出目录,因为每种配置都有不同的输出目录,所以要复制多份(至少包括Debug和Release两个输出目录),这些做…...
leetCode 2578. 最小和分割 + 排序 + 贪心 + 奇偶分组(构造最优解)
2578. 最小和分割 - 力扣(LeetCode) 给你一个正整数 num ,请你将它分割成两个非负整数 num1 和 num2 ,满足: num1 和 num2 直接连起来,得到 num 各数位的一个排列。 换句话说,num1 和 num2 中所…...
自定义实现图片裁剪
要实现这个功能,首先需要创建一个自定义的View,然后在该View中绘制背景框和裁剪后的图片。以下是一个简单的实现: 1. 创建一个名为CustomImageView的自定义View类,继承自View: import android.content.Context; impor…...
开发语言工具编程系统化教程入门和初级专辑课程上线
开发语言工具编程系统化教程入门和初级专辑课程上线 学习编程捷径:(不论是正在学习编程的大学生,还是IT人士或者是编程爱好者,在学习编程的过程中用正确的学习方法 可以达到事半功倍的效果。对于初学者,可以通过下面…...
【Truffle】二、自定义合约测试
一、准备测试 上期我们自己安装部署了truffle,并且体验了测试用例的整个测试流程,实际开发中,我们可以对自己的合约进行测试。 我们首先先明白自定义合约测试需要几个文件 合约文件:既然要测试合约,肯定要有合约的源码…...
场景交易额超40亿,海尔智家三翼鸟开始收获
文 | 螳螂观察 作者 | 余一 随着双十一的到来,国内的消费情绪再次被点燃。在这类大促之下,品牌们就像一个个天体,不断引动着市场潮汐,期待自己能触发更大的“海潮效应”。 所谓“海潮效应”是指,海水因天体的引力而…...
众和策略可靠吗?股票扛杆怎么玩?
可靠 股票扛杆是一种出资战略,经过假贷资金来增加出资金额,从而进步出资收益。这种战略在股票商场中被广泛运用,但一起也伴随着一定的危险。在本文中,咱们将从多个视点来剖析股票扛杆怎么玩。 首要,扛杆出资的原理是…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门  思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
