irpas技术客

分布式协调(配置/注册)_~一叶、

网络投稿 1343

算法

paxos、zab、raft

服务注册与配置

ZooKeeper、Eureka、Nacos、Consul、Etcd

关于CP还是AP的选择:选择 AP,因为可用性高于一致性,所以更倾向 Eureka 和 Nacos;关于Eureka、Nacos如何选择,哪个让我做的事少,我就选择哪个,显然 Nacos 帮我们做了更多的事。【针对cp如果恢复很快,则也可以考虑cp】技术体系:Etcd 和 Consul 都是Go开发的,Eureka、Nacos、Zookeeper 都是Java开发的,可能项目属于不同的技术栈,会偏向选择对应的技术体系。高可用:这几款开源产品都已经考虑如何搭建高可用集群,有些差别而已。产品的活跃度:这几款开源产品整体上都比较活跃。springcloud中的注册中心:eureka 只有1.x,2.0版本官方不在维护。

Zookeeper(CP)

作为一个分布式协同服务,ZooKeeper非常好,但是对于Service发现服务来说就不合适了,因为对于Service发现服务来说就算是返回了包含不实的信息的结果也比什么都不返回要好。所以当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。

但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。

所以说,作为注册中心,可用性的要求要高于一致性!

在 CAP 模型中,Zookeeper整体遵循一致性(CP)原则,即在任何时候对 Zookeeper 的访问请求能得到一致的数据结果,但是当机器下线或者宕机时,不能保证服务可用性。

那为什么Zookeeper不使用最终一致性(AP)模型呢?因为这个依赖Zookeeper的核心算法是ZAB,所有设计都是为了强一致性。这个对于分布式协调系统,完全没有毛病,但是你如果将Zookeeper为分布式协调服务所做的一致性保障,用在注册中心,或者说服务发现场景,这个其实就不合适。

Eureka(AP)工作流程 Eureka Server 启动成功,等待服务端注册。在启动过程中如果配置了集群,集群之间定时通过 Replicate 同步注册表,每个 Eureka Server 都存在独立完整的服务注册表信息。Eureka Client 启动时根据配置的 Eureka Server 地址去注册中心注册服务。Eureka Client 会每 30s 向 Eureka Server 发送一次心跳请求,证明客户端服务正常。当 Eureka Server 90s 内没有收到 Eureka Client 的心跳,注册中心则认为该节点失效,会注销该实例。单位时间内 Eureka Server 统计到有大量的 Eureka Client 没有上送心跳,则认为可能为网络异常,进入自我保护机制,不再剔除没有上报心跳的客户端。当 Eureka Client 心跳请求恢复正常之后,Eureka Server 自动退出自我保护模式。Eureka Client 定时全量或者增量从注册中心获取服务注册表,并且将获取到的信息缓存到本地。服务调用时,Eureka Client 会先从本地缓存找寻调取的服务。如果获取不到,先从注册中心刷新注册表,再同步到本地缓存。Eureka Client 获取到目标服务器信息,发起服务调用。Eureka Client 程序关闭时向 Eureka Server 发送取消请求,Eureka Server 将实例从注册表中删除。

Eureka 为了保障注册中心的高可用性,容忍了数据的非强一致性,服务节点间的数据可能不一致, Client-Server 间的数据可能不一致。比较适合跨越多机房、对注册中心服务可用性要求较高的使用场景。

Nacos(CP | AP)

什么是 Nacos

Nacos是阿里开源的,支持基于 DNS 和基于 RPC 的服务发现。Nacos的注册中心支持CP也支持AP,对他来说只是一个命令的切换,随你玩,还支持各种注册中心迁移到Nacos,反正一句话,只要你想要的他就有。Nacos除了服务的注册发现之外,还支持动态配置服务,一句话概括就是Nacos = Spring Cloud注册中心 + Spring Cloud配置中心。

Consul(CP)

Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其它分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其它工具(比如 ZooKeeper 等)。

Consul 使用起来也较为简单,使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。

CP模型,使用 Raft 算法来保证强一致性,不保证可用性;支持服务注册与发现、健康检查、KV Store功能。支持多数据中心,可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等。支持安全服务通信,Consul可以为服务生成和分发TLS证书,以建立相互的TLS连接。支持 http 和 dns 协议接口;官方提供 web 管理界面。

Etcd(CP)

etcd是一个Go言编写的分布式、高可用的一致性键值存储系统,用于提供可靠的分布式键值存储、配置共享和服务发现等功能。

易使用:基于HTTP+JSON的API让你用curl就可以轻松使用;

易部署:使用Go语言编写,跨平台,部署和维护简单;

强一致:使用Raft算法充分保证了分布式系统数据的强一致性;

高可用:具有容错能力,假设集群有n个节点,当有(n-1)/2节点发送故障,依然能提供服务;

持久化:数据更新后,会通过WAL格式数据持久化到磁盘,支持Snapshot快照;

快速:每个实例每秒支持一千次写操作,极限写性能可达10K QPS;

安全:可选SSL客户认证机制;

ETCD 3.0:除了上述功能,还支持gRPC通信、watch机制。

分布式系统协议(Paxos、Raft、ZAB)

Paxos算法是Leslie Lamport在1990年提出的一种基于消息传递的一致性算法,非常难以理解,基于Paxos协议的数据同步与传统主备方式最大的区别在于:Paxos只需超过半数的副本在线且相互通信正常,就可以保证服务的持续可用,且数据不丢失。

Raft是斯坦福大学的Diego Ongaro、John Ousterhout两个人以易理解为目标设计的一致性算法,已经有了十几种语言的Raft算法实现框架,较为出名的有etcd,Google的Kubernetes也是用了etcd作为他的服务发现框架。

Raft是Paxos的简化版,与Paxos相比,Raft强调的是易理解、易实现,Raft和Paxos一样只要保证超过半数的节点正常就能够提供服务。

ZooKeeper Atomic Broadcast (ZAB, ZooKeeper原子消息广播协议)是ZooKeeper实现分布式数据一致性的核心算法,ZAB借鉴Paxos算法,但又不像Paxos算法那样,是一种通用的分布式一致性算法,它是一种特别为ZooKeeper专门设计的支持崩溃恢复的原子广播协议。

Raft

Follower、Candidate、Leader

图解raft算法:轻松理解Raft算法?

领导人选举过程:

(在Raft算法中,会有两个超时时间设置来控制选举过程:竞选超时、心跳超时)

1.初始化时,所有的节点都是跟随者

2.一段时间后(竞选超时,一般是150毫秒到300毫秒之间的随机数),跟随者没有监听到领导者发来的消息,自己将变成候选人

3.随后,候选人将向其它节点发起一次选举投票请求

4.如果收到请求的节点在当前选举周期中没有投过票,则该节点会投票给这个候选人,然后这个节点重置它的选举周期时间,重新计时

5.如果大多数节点都投票赞同,那么这个候选人将成为"领导人",并向所有节点通知这一消息

6.之后所有的变化指令都由这个领导人来决定,领导人将周期性的发送附加日志指令给跟随者(即心跳包),以此来保证它的领导人地位

7.跟随者将响应?附加日志?消息

8.选举周期将一直持续直到某个跟随者没有收到心跳包并成为候选人

在同一个周期里若有两个节点同时发起了竞选请求...

并且每个都收到了相同个数的跟随者的投票响应,并且都无法获得更多选票

这种情况下,两个节点将等待一轮竞选超时后重新发起竞选请求

日志复制过程:(两次提交(2PC))

1.客户端发指令给领导人,更改指令会先记录到节点的日志里(数据尚未提交,值还没变)

3.然后领导人节点(在下一个心跳)会将变更指令同步到跟随者的节点日志中

4.随后领导人进入等待状态,直到收到大多数节点记录成功的响应

5.这时,领导人将提交这条记录,存储新的值

6.然后领导人通知所有跟随者提交记录

7.最终,集群状态达成一致了

发生分区时(假如A和B分为一组,C、D和E分为一组)

1.由于分区原因,系统中出现了两个不同的领导人(B、D)

2.现在新加一个客户端并且试着修改两个领导人的数据

3.其中一个客户端将把节点B的值设置为"3",但节点B不能同步大多数,所以他的日志记录仍为未提交

4.另一个客户端将修改 节点D 的值为"8",因为可以同步大多数,所以这个操作能够成功

5.随后,我们修复了网络分区问题

6.节点B将会发现存在"更高领导人",所以将会选择"下台"

7.此时,节点A和节点B将会回滚它们未提交的记录,并同步新领导人的日志

8.最终,我们集群达成了一致

任期Term

raft 算法将时间划分为任意长度的任期(term),任期用连续的数字表示,看作当前 term 号。每一个任期的开始都是一次选举,在选举开始时,一个或多个 Candidate 会尝试成为 Leader。如果一个 Candidate 赢得了选举,它就会在该任期内担任 Leader。如果没有选出 Leader,将会开启另一个任期,并立刻开始下一次选举。raft 算法保证在给定的一个任期最少要有一个 Leader。

每个节点都会存储当前的 term 号,当服务器之间进行通信时会交换当前的 term 号;如果有服务器发现自己的 term 号比其他人小,那么他会更新到较大的 term 值。如果一个 Candidate 或者 Leader 发现自己的 term 过期了,他会立即退回成 Follower。如果一台服务器收到的请求的 term 号是过期的,那么它会拒绝此次请求。

ZAB

3种角色:Leader(主)、Follower(从,参与投票)、Observer(观察者,不参与投票)

4种状态:

1、LOOKING:寻找 Leader 状态,当服务器处于该状态时,表示当前集群没有 Leader,因此会进入 Leader 选举状态。

2、FOLLOWING:跟随者状态,表示当前服务器角色是 Follower。

3、LEADING:领导者状态,表示当前服务器角色是 Leader。

4、OBSERVING:观察者状态,表示当前服务器角色是 Observer。

3 种选举方式:

LeaderElectionAuthFastLeaderElectionFastLeaderElection (最新默认)

以下场景进行选举:

1、Zookeeper 集群启动初始化时进行选举

2、Zookeeper 集群 Leader 失联时重新选举

选举前提条件

1、Zookeeper 服务器处于 LOOKING 竞选状态

此时说明 Zookeeper 服务器集群处于群龙无首状态,另外,观察者状态不能参与竞选投票。

2、Zookeeper 集群规模至少要 3 台机器或以上

选举大致流程:

1、初始投票

服务器启动后,每个 Server 都会给自己投上一票,每次投票会包含所投票服务器的 myid 和 zxid,这里使用 Server(myid, zxid)的方式表示,此时的投票结果为:zk1(1, 0),zk2(2, 0),zk3(3, 0)

2、同步投票结果

集群中的服务器在投票后,会将各自的投票结果同步给集群中其他服务器。

3、检查投票有效性

各服务器在收到投票后会检查投票的有效性,如:是否本轮投票,是否来自 LOOKING 状态的服务器的投票等。

4、处理投票

服务器之间会进行投票比对,规则如下:

优先检查事务ID(zxid),较大的服务器优先作为 Leader如果 zxid 相同,则 myid 较大的服务器作为 Leader

如:zk1 和 zk2 进行比对,此时 zk2 胜出,zk1 更新自己的投票为:zk1(2, 0)

5、统计投票结果

每轮投票比对之后都会统计投票结果,确认是否有超过半数的机器都得到相同的投票结果,如果是,则选出 Leader,否则继续投票。

6、更改服务器状态

一旦选出 Leader,每个服务器就会各自更新自己的状态

2、集群重新选举

leader挂掉后,follower又变为LOOKING状态开始选举过程。


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #分布式协调配置注册 #Eureka # #nacos #帮我们做了更多的事