分布式原理
抽屉原理
quorum基于抽屉原理,是对waro的一种取舍折中的方式
中间件一致性方案
zookeeper (zab)
只有一台客户端(Leader)负责处理外部的写事务请求,然后Leader客户端将数据同步到其他Follower节点。可以读
kafka
追随者副本是不对外提供服务的(保证信息都是最新的),不能写不能读
mysql
读写分离,slave可以读
zookeeper中数据副本的同步方式与二段提交相似,但是却又不同。二段提交要求协调者必须等到所有的参与者全部反馈ACK确认消息后,再发送commit消息。要求所有的参与者要么全部成功,要么全部失败。二段提交会产生严重的阻塞问题。
2PC协议(两阶段提交)
两阶段
准备阶段(询问是否准备好了执行事务,执行事务,反馈)
提交阶段(commit请求或者Rollback请求)
优点:
优点:原理简单,实现方便。
缺点:同步阻塞(所有的节点都在等待其他节点的响应),单点问题(协调者),数据不一致(部分参与者收到了commit请求),
容错性不好(任何参与者节点出错都会出问题)。
3PC协议(三阶段提交)
三个阶段分别是:CanCommit(询问),然后再PreCommit(锁资源),最后真正Do Commit(提交)。
在doCommit阶段,如果参与者无法及时接收到来自协调者的doCommit或者rebort请求时,在等待超时之后,会继续进行事务的提交。(其实这个应该是基于概率来决定的,当进入第三阶段时,说明参与者在第二阶段已经收到了PreCommit请求,那么协调者产生PreCommit请求的前提条件是他在第二阶段开始之前,收到所有参与者的CanCommit响应都是Yes。(一旦参与者收到了PreCommit,意味着他知道大家其实都同意修改了)所以,一句话概括就是,当进入第三阶段时,由于网络超时等原因,虽然参与者没有收到commit或者abort响应,但是他有理由相信:成功提交的几率很大。 )
CanCommit类似2PC的准备阶段的事务询问
PreCommit
执行事务预提交或者中断事务
Do Commit
执行提交或者中断事务
相对两阶段:强一致性提高,效率底
ZAB
1)所有的事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被叫做 Leader服务器。其他剩余的服务器则是 Follower服务器。
2)Leader服务器 负责将一个客户端事务请求,转换成一个 事务Proposal,并将该 Proposal 分发给集群中所有的 Follower 服务器,也就是向所有 Follower 节点发送数据广播请求(或数据复制)
3)分发之后Leader服务器需要等待所有Follower服务器的反馈(Ack请求),在Zab协议中,只要超过半数的Follower服务器进行了正确的反馈后(也就是收到半数以上的Follower的Ack请求),那么 Leader 就会再次向所有的 Follower服务器发送 Commit 消息,要求其将上一个 事务proposal 进行提交。
Paxos
第一阶段:决策者确定一个提案(半数以上)
第二阶段:所有提议者手头的提案都是一样的
Raft
Terms
众所周知,在分布式环境中,“时间同步”本身是一个很大的难题,但是为了识别“过期信息”,时间信息又是必不可少的。Raft为了解决这个问题,将时间切分为一个个的Term,可以认为是一种“逻辑时间”。如下图所示:
-
每个Term至多存在1个Leader
-
某些Term由于选举失败,不存在Leader
-
每个Server本地维护currentTerm
阶段一: Leader election(leader选举)
阶段二:Log replication(日志复制)
分为两步,一步为prepare,先确定有多少节点可以成功写入,第二步为confirm,
leader 选举是为了保证日志复制的一致性。Leader 选举只是为了保证日志复制相同的辅助工作。实际上,在更为学术的 Paxos 里面,是没有 leader 的概念的(大部分 Paxos 的实现通常会加入 leader 机制提高性能)。
leader 会接收客户端的所有需求(follower 会将写请求转发给 leader),leader 会将数据以日志的方式通过 RPC 的方式同步给所有 followers,只要超过半数以上的 follower 反馈成功,这条日志就成功提交了。保证一个全局的变更序列被顺序引用。
日志复制类似两阶段提交(2PC),不过与2PC的区别在于,leader只需要大多数(majority)节点的回复即可,这样只要超过一半节点处于工作状态则系统就是可用的
raft算法为了保证高可用,并不是强一致性,而是最终一致性
request请求后在leader节点写入,此时leader节点为uncommited状态,put请求处于等待
+++++++++++++++++++++++++++++++++++++++++++++++++
由一次心跳后,子节点纷纷写入,由于心跳还没传回主节点,主节点为uncommitted状态,put请求仍在等待
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
RPC传回后,代表着prepared成功了,主节点发送commit请求给子节点,注意这个瞬间微妙的点在于,子节点虽然还没接受到committed信息,但子节点已经把记录写入到磁盘了,也就是处于重启不会丢弃的状态,put请求返回
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
在第二次心跳后,所有子节点都已知持久化状态
paxos 算法与 raft 算法的差异
1. raft强调是唯一leader的协议,此leader至高无上
2. raft:新选举出来的leader拥有全部提交的日志,而 paxos 需要额外的流程从其他节点获取已经被提交的日志,它允许日志有空洞