微服务架构实战(持续更新)
2022-02-16 11:27:47 26 举报
AI智能生成
全网最全微服务架构实战学习资料
作者其他创作
大纲/内容
既有架构的形态
起点
好的架构不是设计出来的,是演化而来的,而且一直在演进
终点
拆分的起点和终点是什么?
要考虑的元素和坚持的原则是什么?
子主题
架构是如何演化的?
架构演化
前端服务和后端服务太“胖”了,如何拆分?
简单的微服务架构
i. 形态中包含很多强事务场景的
ii. 业务相对稳定,迭代周期长的
iii. 访问压力不大,可用性要求不高,如oa形态
a) 业务形态不合适的?
1、 哪些情况是是不适合上微服务的?
适合上微服务吗
微服务拆分的起点
a) 解决服务地址配置的问题,解放运维和开发在配置上的负担
1、 分布式系统为什么需要服务发现?
简单直接,不需要代理的接入、客户端知道所有的可用的服务的实例
i. 优点
客户端需要自己实现一套逻辑去吧服务实例挑选出来
ii. 缺点
a) 客户端发现,如eureka就是客户端发现
对调用端是透明的
优点
b) 服务端发现,如Nginx、kubernetes、dubbo使用的zookeeper等就是服务端发现
2、 服务发现的两种方式
比如说eureka是Java语言编写的,那如果其他语言想接入eureka怎么办?
1. 不同的语言
2. 不同的数据库
i. 异构
a) 微服务的特点
i. REST ? RPC
b) springcloud的调用方式
轻量级的通信要么是http的RESTful api接口,要么是RPC。
Eureka支持将非Java语言实现的服务纳入到服务治理体系中来,只是不同语言只需要实现不同的eureka-client即可。
如nodejs实现的eureka-js-client。
Spring cloud选择了RESTful api,eureka server提供了完善的RESTful api。
微服务的一个特点就是轻量级的通信
3、 思考
分布式下服务注册的地位和原理
如何搭建eureka服务呢?
看主要区别的话,三者都可作为注册中心,具体怎么选择可根据 CAP 定理去选择
指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
分布在不同区域的计算机,彼此之间通过网络建立通信,相互协作作为一个整体对外提供服务,这就是集群,如果我们开发的系统具备这样的能力,那么理论上就具备无限横向扩容的能力,系统的吞吐量就会随着机器数增加而增长,那么未来当系统出现高负载的时候,就可以很好地应对这种情况。
为什么需要集群?
通过上面分析,我们知道实现集群,其实就是采用多台计算机来共同承担和负载系统压力,那么就涉及到多台计算机需要参与一起处理数据,为了保证可用性,一般都会在每台计算机上备份一份数据,这样只要有一个节点保持同步状态,那么数据就不会丢失,比如kafka分区多副本、Elasticsearch的副本分片,由于同一数据块及其副本位于不用的机器,随着时间的推移,再加上不可靠的网络通信,所有机器上的数据必然会不完全一致,这个时候假如发生一种极端情况,所有的机器宕机了,又如何保证数据不丢失呢(其实只有两种方法)?
选第一台恢复正常服务的机器(不一定拥有全部数据)作为可信数据来源,快速恢复集群
停机时间优于同步
保证可用性
等待第一台拥有全部数据的机器恢复正常,再恢复集群
kafka参数图鉴-unclean.leader.election.enable
,比如禁用kafka的unclean leader选择机制就是这种策略
Kafka参数图鉴——unclean.leader.election.enable https://blog.csdn.net/u013256816/article/details/80790185
retries
replication.factor
min.insync.replicas
也就是说如果unclean.leader.election.enable参数设置为true,就有可能发生数据丢失和数据不一致的情况,Kafka的可靠性就会降低
如果unclean.leader.election.enable参数设置为false,那么就意味着非ISR中的副本不能够参与选举,此时无法进行新的选举,此时整个分区处于不可用状态,Kafka的可用性就会降低
unclean.leader.election.enable
Kafka可靠性相关的参数
有哪些例子?
同步优于停机时间
保证数据一致性
为什么CAP不能同时满足?
为什么三者不能兼顾呢?
在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
一致性(consistence)
在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
可用性(available)
就是高可用性,一个节点崩了,并不影响其它的节点(100个节点,挂了几个,不影响服务,越多机器越好)
分区容错性(Partition fault tolerance)
一般来讲,基于网络的不稳定性,分布容错是不可避免的,所以我们默认CAP中的P总是成立的。
什么是CAP
其实当大多数机器不可用时,就需要在可用性和一致性之间进行妥协了,所以另一个更符合分布式系统的Base理论又被创造出来了。
https://www.cnblogs.com/Leo_wl/p/12388203.html
Base理论
CAP 定理
在保证数据安全的基础上,保持服务的持续可用,是核心业务对底层数据存储系统的基本要求
业界常见的1主N备的方案面临的问题是“最大可用(Maximum Availability)”和“最大保护(Maximum Protection)”模式间的艰难抉择:
前言
表示主机尽力将数据同步到备机之后才返回成功,如果备机宕机或者网络中断那么主机则单独提供服务,这意味着主备都宕机情况下可能的数据丢失(比如MySQL的半同步模式)
“最大可用”模式
表示主机一定要将数据同步至备机后才返回成功,则意味着在任意备机宕机或者网络中断情况下主机不得不停止服务等待备机或者网络恢复(比如MySQL的全同步模式)
“最大保护(一致性)”模式
传统主备方式是如何做最大可用和最大一致性的?
Eureka&Zookeeper&Consul 原理与对比
Eureka&Zookeeper&Consul 原理与对比
AP 高可用
Eureka是在Java语言上,基于Restful Api开发的服务注册与发现组件,由Netflix开源。遗憾的是,目前Eureka仅开源到1.X版本,2.X版本已经宣布闭源。
是什么?
Server是服务注册中心的角色,为Client提供服务的注册与发现功能
能做什么?
Eureka 采用的是Server/Client的模式进行设计的
Server是服务注册中心的角色,为Client提供服务的注册与发现功能,维护着注册到自身的Client的相关信息,同时提供接口给Client获取到注册表中的所有服务的信息
Server
Client将有关自己的服务的信息通过一定的方式登记在Server上,并在正常范围内维护自己信息的一致性,方便其他服务发现自己,同时可以通过Server获取到自己的依赖的其他服务信息,从而完成服务调用。
Client
架构图
作为Eureka Client,扮演了服务的提供者,提供业务服务,向Eureka Server注册和更新自己的信息,同时能从Eureka Server的注册表中获取到其他服务的信息。
Application Service
扮演服务注册中心的角色,提供服务注册和发现的功能,每个Eureka Cient向Eureka Server注册自己的信息,也可以通过Eureka Server获取到其他服务的信息达到发现和调用其他服务的目的。
Eureka Server
作为Eureka Client,扮演了服务消费者,通过Eureka Server获取到注册到上面的其他服务的信息,从而根据信息找到所需的服务发起远程调用。
Application Client
Eureka Server中的注册表信息的同步拷贝,保持不同的Eureka Server集群中的注册表中的服务实例信息的一致性。提供了数据的最终一致性。
Replicate
服务之间的远程调用。
Make Remote Call
注册服务实例,Client端向Server端注册自身的元数据以进行服务发现。
Register
续约,通过发送心跳到Server维持和更新注册表中的服务实例元数据的有效性。当在一定时长内Server没有收到Client的心跳信息,将默认服务下线,将服务实例的信息从注册表中删除。
Renew
服务下线,Client在关闭时主动向Server注销服务实例元数据,这时Client的的服务实例数据将从Server的注册表中删除。
Cancel
概念
架构
Eureka中没有使用任何的数据强一致性算法保证不同集群间的Server的数据一致,仅通过数据拷贝的方式争取注册中心数据的最终一致性,虽然放弃数据强一致性但是换来了Server的可用性,降低了注册的代价,提高了集群运行的健壮性。
最终一致性,换来高可用
总结
架构&运行机制
Eureka Server 启动流程分析 https://blog.csdn.net/u010647035/article/details/83048894
Eureka
CP 一致性
HashiCorp基于Go语言开发的支持多数据中心分布式高可用的服务发布和注册服务软件,采用Raft算法保证服务的一致性,且支持健康检查。
Consul采用主从模式的设计,使得集群的数量可以大规模扩展,集群间通过RPC的方式调用(HTTP和DNS)。
服务发现场景中consul作为注册中心,服务地址被注册到consul中以后,可以使用consul提供的dns、http接口查询,consul支持health check。
服务发现
http://www.mabiji.com/consul/consul.html
服务隔离场景中consul支持以服务为单位设置访问策略,能同时支持经典的平台和新兴的平台,支持tls证书分发,service-to-service加密。
服务隔离
服务配置场景中consul提供key-value数据存储功能,并且能将变动迅速地通知出去,通过工具consul-template可以更方便地实时渲染配置文件。
docker实例的注册与配置共享、coreos实例的注册与配置共享、vitess集群、SaaS应用的配置共享、Consul与confd服务集成,动态生成nginx和haproxy配置文件或者Consul结合nginx构建高可用可扩展的Web服务。
有哪些例子呢?
服务配置
图
作为一个代理(非微服务实例),它将转发所有的RPC请求到Server中。作为相对无状态的服务,它不持有任何注册信息。
作为一个具备扩展功能的代理,它将响应RPC查询、参与Raft选举、维护集群状态和转发查询给Leader等。
一个数据中心的所有Server都作为Raft节点集合的一部分。其中Leader将负责所有的查询和事务(如服务注册),同时这些事务也会被复制到所有其他的节点。
Leader-Server
数据中心作为一个私有的,低延迟和高带宽的一个网络环境。每个数据中心会存在Consul集群,一般建议Server是3-5台(考虑到Raft算法在可用性和性能上取舍),而Leader只能唯一,Client的数量没有限制,可以轻松扩展。
Data Center
https://vincentwang.gitee.io/raft/?nsukey=bj4prOKvAFRLTniAapAZ1JOAxSuL3Y9moCpuI9CfF8vDGf6iblXp6pOu0HjxQp%2Fl6Q9VuPgjVcuiW57X06QUxLeJqtH98mOPdSahIE8rqmalLZ%2FDfGULr1bhcfgl5ywsdsP37Z5Iw5m1TN3IrIswDkBWautO5A17YLyEhONaAwpan2KyaZsXgzRebd0%2BHY2aUgTMj%2FgAmWyBii99unh%2FKA%3D%3D
动画演示raft算法
动画演示raft的原理
Leader处理所有的查询和事务,并向Follower同步事务
数据的一致性以Leader中的数据为准实现。
Leader
Follower会将所有的RPC查询和事务转发给Leader处理,它仅从Leader接受事务的同步
Follower
Candidate候选者
角色
节点的Raft状态机将处于Follower状态等待来来自Leader节点的心跳
首先,节点加入时为follower状态。当节点超过一定时间没有收到notifyLeader消息就会调用switchToCandidate方法,切换到candidate状态。具体如下:
然后,每个节点收到notifyLeader消息,都会做相应的处理。其处理流程如下:
注:当一定时间间隔没有收到term>=CurrentTerm的notifyLeader,就会调用switchToCandidate方法。
如果在一定时间周期内没有收到Leader节点的心跳,节点将发起选举。
Follower节点选举时会将自己的状态切换为Candidate,然后向集群中其它Follower节点发送请求,询问其是否选举自己成为Leader。
当收到来自集群中过半数节点的接受投票后,节点即成为Leader,开始接收Client的事务处理和查询并向其它的Follower节点同步事务。
Follower节点
Leader节点会定时向Follower发送心跳来保持其地位。
Leader节点
节点初始启动
每个节点都会缓存一个term值
每竞选一次都会递增一次term
每个节点只投票竞选序号大于缓存的term值的竞选请求
当节点投票竞选请求时,会将term值设置为请求中的竞选序号值
当有过半的节点投票通过,就会升级为leader节点
当leader节点向所有节点通知自己竞选成功序号的心跳时,其他节点收到后就会进入follower状态。
raft算法选主过程 https://blog.csdn.net/fs3296/article/details/106743503
raft选主算法
具体实现
运行原理
etcd用在 k8s信息存储上,用raft实现强一致性
强一致性
Alluxio的文件系统元数据存储以及master选主使用了raft算法。具体使用的是copycat这一raft的java实现
consul 中的Leader Server选主
master选主
原生算法三个状态扩展为五个状态:leaderUnReady、leaderReady、followerUnReady、followerReady和candidate
leaderUnReady和leaderReady都是leader状态,前者是刚刚成为leader且正在进行数据同步、只提供对数据只读操作,后者是成为leader且数据同步完成、对数据提供读写操作;
leader状态
followerUnReady和followerReady都是follower状态,前者是刚刚成为follower且正在进行数据同步、只提供对数据只读操作,后者是成为follower且数据同步完成、对数据提供读写操作;
follower状态
candidate与原生算法一致,不作额外说明。
candidate
竞选过程与原生算法基本一致,其中RaceTerm的递增算法是为了保证最后已提交的binLog包含在新选出的LeaderNode中。此外,Leader和Follower状态分为ready和unready两种。
当一定时间没有收到newTerm>=CurrentTerm的心跳时,就会调用switchToCandidate启动竞选。特别地,对于Leader节点和非Leader节点接收到消息时的状态设置,有所不一样;Leader节点在LeaderUnReadyState状态下不提供写操作,需要待LeaderRecover完毕并切换为LeaderReadyState状态才可进行写操作。此外,对于follower节点,也是先进入FollowerUnReadyState后,待FollowerRecover完毕切为FollowerReadyState才能接受主节点写入同步。————————————————版权声明:本文为CSDN博主「Victor Fung」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/fs3296/article/details/106743503
如何处理心跳?
注:一旦主节点将binLog写入成功后,就会向所有的从节点同步binLog、直到过半返回success。从节点收到binLog后,首先拉取还未同步到的binLog;所有的binLog有序执行到XA Prepare阶段;主节点在最后commitXA后,会将prepare状态的xid通知给所有的从节点,然后从节点commit不在prepareXidList中挂起的事务。特别地,需要保证不同节点生成的xid不能出现相同的情况。此外,leader除了有事务提交时会发送notifyPrepareXidList消息外,还会定时进行发送notifyPrepareXidList消息。————————————————版权声明:本文为CSDN博主「Victor Fung」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/fs3296/article/details/106743503
如何写入数据呢?
假定有编号为0到9十个节点,其中0号为主节点。其中0号成功提交了binlog序号为5的事务,且在1到9号节点也已都同步提交;
然后0号节点有序发起了binlog序号为6、7的事务,但是由于网络原因只有7、8、9号三个节点返回成功,然后0节点突然宕机。此时1到6号节点没有未提交的binglog,且最后提交的binglog序号为5;7到9号节点都有binlog序号为6、7的事务未提交;
这时,1到9号会执行主节点选举。假设,此时1到6号在一个机房、7到9号在另一个机房,然后两个机房通信出了故障,那么此时1到6号就会成功竞选一个主节点,假设为1号;当然7到9号会一直处于竞选状态;
1号节点再发起了一个序号为6的binlog,假设2到6都成功返回,那么此时1到6号节点的序号为6的binglog与7到9号节点中序号为6的binlog是不一致的。如何此时1到6的机房连接7到9的机房网络恢复,那么7到9中某个节点成功竞选成了主节点后,此时就会有不一致的数据。
为什么要处理冲突呢?
注:当节点重启后,若状态为leaderUnReady或leaderReady,也会执行leaderRecover。它将所有prepare状态的binglog依次同步到所有从节点。如果success返回过半,就提交XA事务(此外,还有需要记录这些被延迟提交、没有成功返回的XA事务),然后continue循环;反之,就会持续发起recover同步。特别地,如果中途接收到冲突,就记录下来并发给运维人员。————————————————版权声明:本文为CSDN博主「Victor Fung」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/fs3296/article/details/106743503
leader如何复位?
当节点重启后,若状态为followerUnReady,也会执行followerRecover。followerRecover将回滚与主节点不一致的XA事务、或binLogNum比主节点lastBinLogNum大的XA事务。
follower如何复位呢?
如何选主呢?
数据操作算法
数据节点的加入/移除,可以看成也是一种对数据的写入。只是这里的数据就是节点信息表内容的添加或删除
节点加入是向系统NodeTable中插入节点;然后启动串行化读,串行化事务隔离是为了在拉取db数据时,防止被后续事务污染,当然如果采用MVCC下的repeatable-read隔离更好。
节点加入
与节点加入一样,只是在NodeTable中删除自己。
节点移除
每次加入节点个数必须少于一半;
每次移除节点个数必须少于一半;
注意事项
节点加入/移除
主从备份
用处
当有四个节点A、B、C、D,A和B同时发起竞选节点且reqTerm值为1;其中A和B先收到A的请求,给予了A投票,而C和D先收到B的请求,给予了B投票;依次第二次、第三次。。。最后造成死循环而无法过半通过、竞选不出leader。
在节点发起第一次请求超时后,给予节点一个随机的超时间隔。特别地,随机超时间隔所在区间不要超过某个上限。
如何解决呢?
当节点数为偶数且偶数个节点同时发起竞选时,会死循环
缺点
raft算法
raft算法(选主协议即分布式一致性的协议)
传统事件通知是由master或者leader节点来做通知,压力很大
Gossip协议是为了解决分布式环境下监控和事件通知的瓶颈
消息通知
术语
Gossip协议中的每个Agent会利用Gossip协议互相检查在线状态,分担了服务器节点的心跳压力,通过Gossip广播的方式发送消息。
所有的Agent都运行着Gossip协议。
服务器节点和普通Agent都会加入这个Gossip集群,收发Gossip消息。
每隔一段时间,每个节点都会随机选择几个节点发送Gossip消息,其他节点会再次随机选择其他几个节点接力发送消息。
这样一段时间过后,整个集群都能收到这条消息。
架构&运行原理
Gossip协议(消息广播)
基于Raft算法,Consul提供强一致性的注册中心服务,但是由于Leader节点承担了所有的处理工作,势必加大了注册和发现的代价,降低了服务的可用性
基于Raft算法
通过Gossip协议,Consul可以很好地监控Consul集群的运行,同时可以方便通知各类事件,如Leader选择发生、Server地址变更等。
基于Gossip协议
consul总结
Consul
CP
Paxos算法是Leslie Lamport在1990年提出的一种基于消息传递的一致性算法。由于算法难以理解,起初并没有引起大家的重视,Lamport在1998年将论文重新发表到TOCS上,即便如此Paxos算法还是没有得到重视,2001年Lamport用可读性比较强的叙述性语言给出算法描述。
06年Google发布了三篇论文,其中在Chubby锁服务使用Paxos作为Chubby Cell中的一致性算法,Paxos的人气从此一路狂飙。br style=\
基于Paxos协议的数据同步与传统主备方式最大的区别在于:Paxos只需超过半数的副本在线且相互通信正常,就可以保证服务的持续可用,且数据不丢失。
与传统主备方式最大的区别
Basic-Paxos解决的问题:在一个分布式系统中,如何就一个提案达成一致。
Proposer选择一个提案编号n并将prepare请求发送给 Acceptor。
Acceptor收到prepare消息后,如果提案的编号大于它已经回复的所有prepare消息,则Acceptor将自己上次接受的提案回复给Proposer,并承诺不再回复小于n的提案。
Prepare阶段:
当一个Proposer收到了多数Acceptor对prepare的回复后,就进入批准阶段。它要向回复prepare请求的Acceptor发送accept请求,包括编号n和根据prepare阶段决定的value(如果根据prepare没有已经接受的value,那么它可以自由决定value)。
在不违背自己向其他Proposer的承诺的前提下,Acceptor收到accept请求后即接受这个请求。
Accept阶段:
两阶段提交协议?
怎么做到呢?
当存在一批提案时,用Basic-Paxos一个一个决议当然也可以,但是每个提案都经历两阶段提交,显然效率不高。Basic-Paxos协议的执行流程针对每个提案(每条redo log)都至少存在三次网络交互:1. 产生log ID;2. prepare阶段;3. accept阶段。
缺点?
Basic-Paxos
Mulit-Paxos解决的问题:在一个分布式系统中,如何就一批提案达成一致。
解决Basic-Paxos的效率问题
所以,Mulit-Paxos基于Basic-Paxos做了优化,在Paxos集群中利用Paxos协议选举出唯一的leader,在leader有效期内所有的议案都只能由leader发起。
即leader有效期内不会有其他server提出的议案。
因此,对于后续的提案,我们可以简化掉产生log ID阶段和Prepare阶段,而是由唯一的leader产生log ID,然后直接执行Accept,得到多数派确认即表示提案达成一致(每条redo log可对应一个提案)。
这里强化了协议的假设
为什么出现Mulit-Paxos?
Mulit-Paxos
Paxos
https://zhuanlan.zhihu.com/p/46531628
Paxos与Raft的前世今生
https://www.cnblogs.com/kevingrace/p/12433503.html
对于一个集群,想要提高这个集群的可用性,通常会采用多机房部署,那么如果机房之间的网络断了之后,两个机房内的zkServer还是可以相互通信的,如果不考虑过半机制,那么就会出现每个机房内部都将选出一个Leader。这就相当于原本一个集群,被分成了两个集群,出现了两个\"大脑\",这就是所谓的\"脑裂\"现象。
多机房部署
由于心跳超时(网络原因导致的)认为leader死了,但其实leader还存活着。
由于假死会发起新的leader选举,选举出一个新的leader,但旧的leader网络又通了,导致出现了两个leader ,有的客户端连接到老的leader,而有的客户端则连接到新的leader。
网络原因
什么是脑裂?
在领导者选举的过程中,如果某台zkServer获得了超过半数的选票,则此zkServer就可以成为Leader了。
举个简单的例子:如果现在集群中有5台zkServer,那么half=5/2=2,那么也就是说,领导者选举的过程中至少要有三台zkServer投了同一个zkServer,才会符合过半机制,才能选出来一个Leader。
举个例子?
因为这样不需要等待所有zkServer都投了同一个zkServer就可以选举出来一个Leader了,这样比较快,所以叫快速领导者选举算法。
那么zookeeper选举的过程中为什么一定要有一个过半机制验证?
此时过半机制的条件是 \"节点数 > 2\",也就是至少要3台服务器才能选出一个Leader,此时机房件的网络断开了,对于机房1来说是没有影响的,Leader依然还是Leader,对于机房2来说是选不出来Leader的,此时整个集群中只有一个Leader。因此总结得出,有了过半机制,对于一个Zookeeper集群来说,要么没有Leader,要么只有1个Leader,这样zookeeper也就能避免了脑裂问题。
如果假设我们现在只有5台机器,也部署在两个机房:
这就是更脑裂问题有关系了,比如回到上文出现脑裂问题的场景 [如上图1]:当机房中间的网络断掉之后,机房1内的三台服务器会进行领导者选举,但是此时过半机制的条件是 \"节点数 > 3\",也就是说至少要4台zkServer才能选出来一个Leader,所以对于机房1来说它不能选出一个Leader,同样机房2也不能选出一个Leader,这种情况下整个集群当机房间的网络断掉后,整个集群将没有Leader。而如果过半机制的条件是 \"节点数 >= 3\",那么机房1和机房2都会选出一个Leader,这样就出现了脑裂。这就可以解释为什么过半机制中是大于而不是大于等于,目的就是为了防止脑裂。
如果假设我们现在只有6台机器,也部署在两个机房:
目的就是为了防止脑裂。
zookeeper过半机制中为什么是大于,而不是大于等于?
zookeeper的过半机制
span style=\
集群中最少的节点数用来选举leader保证集群可用。
在zookeeper中Quorums作用如下
因为每当新leader产生时,会生成一个epoch标号(标识当前属于那个leader的统治时期),这个epoch是递增的,followers如果确认了新的leader存在,知道其epoch,就会拒绝epoch小于现任leader epoch的所有请求。
epoch最大的就是新leader
follower如何识别哪个是最新的leader?
假设某个leader假死,其余的followers选举出了一个新的leader。这时,旧的leader复活并且仍然认为自己是leader,这个时候它向其他followers发出写请求也是会被拒绝的。
因此,得不到大多数支持的写是无效的,旧leader即使各种认为自己是leader,依然没有什么作用。
Zookeeper的写也遵循quorum机制
Zookeeper的写如何保证是写到新额度leader呢?
默认采用了Quorums这种方式来防止\"脑裂\"现象。
例如双线条线,尽量减少“裂脑”发生机会。
添加冗余的心跳线
正在服务一方锁住共享磁盘,\"裂脑\"发生时,让对方完全\"抢不走\"共享磁盘资源。但使用锁磁盘也会有一个不小的问题,如果占用共享盘的一方不主动\"解锁\",另一方就永远得不到共享磁盘。现实中假如服务节点突然死机或崩溃,就不可能执行解锁命令。后备节点也就接管不了共享资源和应用服务。于是有人在HA中设计了\"智能\"锁。
不好的做法是什么?
即正在服务的一方只在发现心跳线全部断开(察觉不到对端)时才启用磁盘锁。平时就不上锁了。
好的做法是什么?
启用“智能”磁盘锁
例如设置参考IP(如网关IP),当心跳线完全断开时,2个节点都各自ping一下 参考IP,不通则表明断点就出在本端,不仅\"心跳\"、还兼对外\"服务\"的本端网络链路断了,即使启动(或继续)应用服务也没有用了,那就主动放弃竞争,让能够ping通参考IP的一端去起服务。更保险一些,ping不通参考IP的一方干脆就自我重启,以彻底释放有可能还占用着的那些共享资源。
设置仲裁机制
还可以做什么预防脑裂?
Quorums (法定人数) 方式
集群中采用多种通信方式,防止一种通信方式失效导致集群中的节点无法通信。
采用Redundant communications (冗余通信)方式
比如能看到共享资源就表示在集群中,能够获得共享资源的锁的就是Leader,看不到共享资源的,就不在集群中。
Fencing (共享资源) 方式
还有哪些方式预防脑裂?
zookeeper如何避免脑裂?
从资源节省的角度来考虑,zookeeper集群的节点最好要部署成奇数个!
一、 Zookeeper 集群节点为什么要部署成奇数
背景
Zookeeper集群\"脑裂\"问题 - 运维总结
Zookeeper
还有哪些组件可以作为注册中心?
Eureka 服务治理
zuul API网关服务
ribbon 客户端负载均衡
Feign 声明式服务调用
Config 统一配置中心
微服务组件
微服务架构实战
收藏
0 条评论
下一页