本文讲分布式的共识概念,算法,应用。涉及到raft,paxos(basic,multi,fast),zk,etcd,chubby。以及思考。关注与如何共识,对于zk,etcd,chubby的接口如何应用于服务发现,分布式锁等略过。html
共识:一个或多个节点提出提案,算法选择一个值。一致赞成,完整(只决定一次),有效(节点投票是有效值,是被提议的值),终止(宕机不回来)。
paxos彻底符合,但raft,zap考虑的是宕机还会回来的状况,用日志保证。能解决上篇(https://segmentfault.com/a/11...)中诸如如下问题:
全序广播至关于重复多伦共识:raft和zap等直接实现全序广播,mutil-paxos也是,都有leader,只决定值的顺序。有固定leader比每一个节点写入,leader维持全序,其余节点同步,冲突少(若没有leader paxos那种要先同步一遍获取最大值,再投票,多了一次pre),画一个有领导和无领导每一个带序号的图能够很好理解带leader会容易些,但单leader有瓶颈。
单领导类的共识:1选出一位领导者,2对领导者的提议进行表决(防止1,一个节点相信本身是领导)投票是同步的,动态成员扩展难,依靠超时检测节点失效,若只有一条特定网络不可靠,会进入领导频繁二人转局面。有领导后也不能领导决定,防止从新恢复等多领导定的状况。
缺点:要多数都赞成,很慢。基本动态扩容很难,手动好比etcdnode
随机的超时时间
。选term大,log长
的 2.leader会把本身的log复制到其余机器,若是新达到多数而且此任期内已有数据过半(挂前的一次数据不会被重复提交)就提交,只提交新任期的,同步follower仍是要同步。上面这个是https://www.microsoft.com/en-...。为了方便理解,去除了实现细节。实时应用中,客户端不会本身处理冲突+1再次投票和发送给其余leaner,这些应该由另外一个角色,在basic中,由一群c协调者,能够和acceptor同样,或者是其中的部分构成,每轮随机一个c做为leader,负责收集本轮结果和通知leaner。proposal->leader(每一个client随机发就能够做为本轮leader)->pre->acceptors返回最大N的值V->带N请求->acceptors->leader->返回给proposal->client失败或者成功或再次投票->投票成功后发给leaner。此过程当中CLIENT2再次发送是另外一个leader。算法
若leader发现没有冲突,再也不参与
,proposal直接提交给acceptor(同一轮只投给先到的),直接发送给leaner,能够理解为基于乐观锁的思想,leaner和CLIENT都自行决议,chubby就是一个典型的Muti-Paxos算法应用,在Master稳定运行的状况下,只须要使用同一个编号来依次执行每个Instance的Promise->Accept阶段处理。数据库
选主时每一个follower只能投一次
,不成功随机时间下一次。有主时的共识由主来给日志编号,follower比较就好,follower保证稳定可替换便可。zap在无主的时候选举算法和fast paxos很像
,有最大xid(相似pre阶段,只不过是上次存好的),先选主,每次选主的提案直接给acceptor而且采用无协调者的冲突处理。在有主时,用paxos的思想先pre收集并同步信息保证一致,主处理写,多数处理成功后回复。zk定位于分布式协调服务
官方:https://zookeeper.apache.org/...
下面介绍zk的经常使用功能,架构,共识过程。apache
自己的数据组织以文件形式,每一个叶节点znodes,非页节点只是命名空间的路径标识;可是存储于内存,记录磁盘日志,副本包含完整内存数据和日志,znodes维护节点的版本,zxid等全部信息。 Zookeeper对于每一个节点QuorumPeer的设计至关的灵活,QuorumPeer主要包括四个组件:客户端请求接收器(ServerCnxnFactory)、数据引擎(ZKDatabase)、选举器(Election)、核心功能组件(Leader/Follower/Observer不一样)
1.单独zk集群元数据的可靠性和一致性保证,元数据保存在zk全部副本中(少许彻底能够放在内存中数据)
路由,选择数据库,调度程序
2.单独zk集群,锁,防御令牌,获取锁或者zxid
3.变动通知,每一个变动都会发送到全部节点
watch机制
4.用于检测,服务发现
session:
每一个ZooKeeper客户端的配置中都包括集合体中服务器的列表。在启动时,客户端会尝试链接到列表中的一台服务器。若是链接失败,它会尝试链接另外一台服务器,以此类推,直到成功与一台服务器创建链接或由于全部ZooKeeper服务器都不可用而失败。
只要一个会话空闲超过必定时间,均可以经过客户端发送ping请求(也称为心跳)保持会话不过时。ping请求由ZooKeeper的客户端库自动发送,所以在咱们的代码中不须要考虑如何维护会话。这个时间长度的设置应当足够低,以便能档检测出服务器故障(由读超时体现),而且可以在会话超时的时间段内从新莲接到另一台服务器。segmentfault
采用了递增的事务id号(zxid)来标识事务。全部的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。服务器
zab protocol网络
Leader election leader选举过程,electionEpoch自增,在选举的时候lastProcessedZxid越大,越有可能成为leader Discovery: 第一:leader收集follower的lastProcessedZxid,这个主要用来经过和leader的lastProcessedZxid对比来确认follower须要同步的数据范围 第二:选举出一个新的peerEpoch,主要用于防止旧的leader来进行提交操做(旧leader向follower发送命令的时候,follower发现zxid所在的peerEpoch比如今的小,则直接拒绝,防止出现不一致性) Synchronization: follower中的事务日志和leader保持一致的过程,就是依据follower和leader之间的lastProcessedZxid进行,follower多的话则删除掉多余部分,follower少的话则补充,一旦对应不上则follower删除掉对不上的zxid及其以后的部分而后再从leader同步该部分以后的数据 Broadcast 正常处理客户端请求的过程。leader针对客户端的事务请求,而后提出一个议案,发给全部的follower,一旦过半的follower回复OK的话,leader就能够将该议案进行提交了,向全部follower发送提交该议案的请求,leader同时返回OK响应给客户端
实际上zookeeper中算法三阶段:FSE=>Recovery=>Broadcast(广播和上面的一致)session
fast leader election
基于fast paxos。发送给全部的节点。没有随机leader参与收集。架构
LOOKING:进入leader选举状态 FOLLOWING:leader选举结束,进入follower状态 LEADING:leader选举结束,进入leader状态 OBSERVING:处于观察者状态 1.serverA首先将electionEpoch自增,而后为本身投票 2 serverB接收到上述通知,而后进行投票PK 若是serverB收到的通知中的electionEpoch比本身的大,则serverB更新本身的electionEpoch为serverA的electionEpoch 若是该serverB收到的通知中的electionEpoch比本身的小,则serverB向serverA发送一个通知,将serverB本身的投票以及electionEpoch发送给serverA,serverA收到后就会更新本身的electionEpoch 在electionEpoch达成一致后,就开始进行投票之间的pk,优先比较proposedEpoch,而后优先比较proposedZxid,最后优先比较proposedLeader pk完毕后,若是本机器投票被pk掉,则更新投票信息为对方投票信息,同时从新发送该投票信息给全部的server。若是本机器投票没有被pk掉,若是是looking,过半更改状态,若是FOLLOWING/LEADING说明落后,加速收敛
常常应用于配置共享和服务发现,相比于zk,简单。使用 Go 语言编写部署简单;使用 HTTP 做为接口使用简单;使用 `Raft 算法`保证强一致性让用户易于理解。无需安装客户端。提供接口K-V存储(storing up to a few GB of data with consistent ordering,提供线性读),watch,lease,lock,election。由于共识彻底实现的raft因此只简单说下部署模式,节点组成,数据持久化等。 官方:https://coreos.com/etcd/docs/latest/
单节点以下
store:为用户提供API
集群会区分proxy,leader,follower
GFS和Big Table等大型系统都用他来解决分布式协做、元数据存储和Master选择等一系列与分布式锁服务相关的问题
客户端发送到其余机器都会将master反馈,从新转到master,持续直到换。
数据组织方式和zk同样。
只有主节点提供读写(数据和日志有空洞),高可靠和可用,吞吐量不如zk。在换主阶段会阻塞。
由于zk,etcd都会补齐follower。所以主从均可以读。etcd的主是固定的,除非故障=》raft的换主。chubby(06年)用过的mutil-poxas主通常不变,不保证每轮主从数据一致,只有主有读写能力,吞吐量会差一些,一万台机器分布式锁仍是能够的。etcd(14年)是后来的,确定更好啊,有http接口,一切都更轻量简单,缺点只是无端障自恢复吧,zk每次都会选主(但基于一个xid,基本也相似mutil-poxas会稳定),可自动恢复。