赞
踩
一致性问题就是相互独立的节点之间如何达成一项决议的问题。分布式系统中,进行数据库事务提交(commit transaction)、Leader选举、序列号生成等都会遇到一致性问题。
工程实践上根据具体的业务场景,或保证强一致(safety),或在节点宕机、网络分化的时候保证可用(liveness)。2PC、3PC是相对简单的解决一致性问题的协议,下面我们就来了解2PC和3PC。
它分成两个阶段(提议+提交/回滚
)
3PC可解决异步网络+节点宕机恢复的系统一致性,它分成三个阶段(提议+准备提交+提交/回滚
):
由于有了阶段二的准备提交阶段,各节点不会阻塞等待提交;并且当有节点宕机时coordinator通过ack获知哪个节点宕机,可以直接commit,当宕机节点恢复后再询问已提交的节点实现同步保证一致性。
CAP在工程中的实际意义是:
(1)调用端保证可用性A
;
(2)被调用端保证最终一致性(EC)
;
(3)允许出现网络分区,并保证服务可用(P)
;
现实生活中物理时间有统一的标准,而分布式系统中每个节点记录的时间并不一样,即使设置了 NTP 时间同步节点间也存在毫秒级别的偏差。因而分布式系统需要有另外的方法记录事件顺序关系,这就是逻辑时钟(logical clock),主要有一下三种:
分布式系统中按是否存在节点交互可分为三类事件,一类发生于节点内部,二是发送事件,三是接收事件。Lamport时间戳原理如下:
Vector clock是在Lamport时间戳基础上演进的另一种逻辑时钟方法,它通过vector结构不但记录本节点的Lamport时间戳,同时也记录了其他节点的Lamport时间戳。Vector clock的原理与Lamport时间戳类似,使用图例如下:
节点B上的第4个事件p (A:2,B:4,C:1) 与节点C上的第2个事件 q(B:3,C:2) 没有因果关系, Tq[B] > Tp[B] 且 Tq[C] < Tp[C],则认为p、q同时发生属于同时发生事件。
分布式系统中数据一般存在多个副本(replication),多个副本可能被同时更新,这会引起副本间数据不一致,Version vector的实现与Vector clock非常类似[8],目的用于发现数据冲突。下面通过一个例子说明Version vector的用法:
- client端写入数据,该请求被Sx处理并创建相应的vector ([Sx, 1]),记为数据D1
Paxos协议在节点宕机恢复、消息无序或丢失、网络分化的场景下能保证决议的一致性,是被讨论最广泛的一致性协议。
Paxos中的节点存在5中角色:client, acceptor, proposer, learner, 和 leader,实际实现中,一个服务可以扮演多个角色。
Basic Paxos可分为以下两个阶段:
每个Prepare消息都有唯一的提议id=n
; n必须比该Proposer之前用过的所有编号都大,一般来说我们可以以数字递增的方式来实现这个编号, Proposer把[n,v]发送给Acceptor(v表示提议的值)同时保证(promise)不再接受ID小于n的提议
即记录曾接受的ID最大的提议,因proposer需要问询该信息以决定提议值
)。 当(n,z)消息被Acceptor确认时,Acceptor会发送一个Accepted(n,z)消息给Proposer 和所有的Learner。当然在大部分情况下Proposer和Learner这两个角色可以合并。如果Leader足够稳定的话,Phase 1 里面的Prepare完全可以省略掉,从而使用同一个Leader去发送Accept消息。当然我们还要对请求消息做一些改造,这里我们在请求里面加入了轮数I,每过一轮,I+1 。
Paxos偏向于理论,在生产环境中基于Paxos实现一个正确的分布式系统非常难,Raft的更利于理解、更易于实行。
(1)为达到更容易理解和实行的目的,Raft将问题分解和具体化:
Raft结构相关重点:
唯一Leader统一处理变更操作请求,简化了实现方法。
,一致性模块相互通信保证节点间操作日志副本(log replication)一致(保证指令追加的顺序和内容一致),节点运行相同状态机(state machine)运行相同顺序和内容的指令得到一致结果。
,以(leader任期)term作为逻辑时钟(logical clock)保证时序,log中index保存追加位置;log条目会记录两者,一致性则体现在log中的term和index都相同
,保证日志一致性相关重点:
所有服务维护nextIndex(指令id)保证指令完整一致,leader追加指令时nextIndex初始化为log的index+1,follower同步log会从和leader最初不一致的地方追加覆盖,实现日志同步及恢复
leader必须存储了所有已提交的指令日志;只有 leader 当前任期(term)内的日志条目才通过计算副本数目达到半数的方式来提交,之前的所有日志条目会随当前term提交而被间接地提交
leader选举相关重点:
随机设置candidate选举超时时间,使各candidate任期号很快就各不相同,防止多个follow同时成为candidate且同时超时后再将term+1还以相同term选举导致的分票无法选出leader
(2)Candidate:
(3)Raft的具体过程如下:
(4)raft遵循几条性质:
(5)nextIndex:
宕机、网络分化等情况可引起Leader重新选举(每次选举产生新Leader的同时,产生新的term)、Leader/Follower间状态不一致。Raft中Leader为自己和所有Follower各维护一个nextIndex值
,其表示Leader紧接下来要处理的指令id以及将要发给Follower的指令id, leader 将所有 nextIndex 的值都初始化为自己最后一个日志条目的 index 加1,LnextIndex不等于FnextIndex时代表Leader操作日志和Follower操作日志存在不一致,这时将从Follower操作日志中最初不一致的地方开始,由Leader操作日志覆盖Follower,直到LnextIndex、FnextIndex相等。
引用了博客园:《从 Paxos 到> Zookeeper——分布式一致性原理和实践》
引用了简书:《Zookeeper——一致性协议:Zab协议》
(1)Zab协议描述:
(2)Zab协议重点:
Zab结构重点:Zab就是崩溃恢复和消息广播两种模式循环切换的过程
消息广播:类似于2PC,加入了队列实现异步解耦防止同步阻塞,提高性能
崩溃恢复:一旦 Leader 服务器出现崩溃或者由于网络原因导致 Leader 服务器失去了与过半 Follower 的联系,那么就会进入崩溃恢复模式 。崩溃恢复包括Leader选举和数据恢复。
leader中不能包含未提交的Proposal,且leader中包含最大的zxid的事务
Zab为每一个事务配置了一个唯一的64位zxid,高32位代表Leader唯一epoch(年代),低32位随新事务出现而递增
保证数据一致性相关重点
同步:Leader维护了一个保持同步Follower的列表,故障恢复即 Follower 将所有尚未同步的已提交事务 都从 Leader 服务器上同步过来并且应用到内存数据中以后,Leader 才会把该 Follower 加入到同步Follower 列表中
抛弃:flowers只听从epoch(zxid高32位)大的Leader的指令,每重新选举都会将epoch+1。如果flower中有上一个Leader未提交的Proposal则当前Leader会发出让其回滚的指令
Leader选举相关重点
leader中不能包含未提交的Proposal,且leader中包含最大的zxid(即epoch大且事务id大)的事务
(3)Zab协议过程:
当整个集群启动过程中,或者当 Leader 服务器出现网络中弄断、崩溃退出或重启等异常时,Zab协议就会 进入崩溃恢复模式,选举产生新的Leader。
当选举产生了新的 Leader,同时集群中有过半的机器与该 Leader 服务器完成了状态同步(即数据同步)之后,Zab协议就会退出崩溃恢复模式,进入消息广播模式。
这时,如果有一台遵守Zab协议的服务器加入集群,因为此时集群中已经存在一个Leader服务器在广播消息,那么该新加入的服务器自动进入恢复模式:找到Leader服务器,并且完成数据同步。同步完成后,作为新的Follower一起参与到消息广播流程中。
相同点:
唯一Leader
:Zab 协议和我们之前看的 Raft 协议实际上是有相似之处的,比如都有唯一一个 Leader负责发送请求到follower,用来保证一致性(Paxos 并没有使用唯一 Leader 机制保证一致性)。半数成功机制
:采取过半即成功的机制保证服务可用(实际上 Paxos 和 Raft 都是这么做的)。逻辑时钟都包含Leader信息
:Zab的逻辑时钟是epoch(Leader世代)+事务id组成的zxid;Raft的逻辑时钟就是term(Leader任期),但由于两者实现一致性的方式不同,Raft通过nextindex标记指令序号。不同点
一致性实现方式不同
:Zab为广播数据,Raft为发送指令、保存指令日志、状态机执行指令同步机制不同
:Zab的Follower通过Learner实现同步,Raft通过状态机执行指令实现同步。数据发送路径不同
:Zab数据发往每个Follower的FIFO队列实现异步解耦广播,Raft指令发往每个Follower的同步模块实现解耦并保证各Follower接收的指令顺序和内容相同(各同步模块相互通信)。Leader选举细节不同
:Zab是Leader必须包含全部提交的Proposal且zxid最大,若zxid相同则选择Zookeeper集群中myid最大的为Leader;Raft的Leader必须包含全部已经提交的指令且term最大,采取随机超时选举时间保证term值不同则确保选出Leader。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。