提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
一、CAP和BASE理论
CAP定理
- Consistency(强一致性):数据在多个副本之间是否能够保持一致性的特点。当一个系统在数据一致性的状态下执行更新操作后,应该保证系统的数据仍然处于一致性的状态。
- Availability(可用性):可用性是指系统提供的服务必须一致处于可用的额状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果。
- Partition tolerance(分区容错性):分布式系统在遇到任何网络分区故障的时候,仍然需要保证对外提供满足一致性和可用性的服务。
BASE理论
BASE理论是基于CAP定理逐步演化而来的,其核心思想实际是无法做到强一致性,单每个应用都可以根据自身的业务,采用适当的方式来使系统达到最终一致性。
-
Basically Available(基本可用):分布式系统在出现不可预知的故障额时候,允许损失部分可用性。
(1)响应时间上的损失:响应等待
(2)功能的损失:降级 -
Soft state(软状态):运行系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步存在延时。
-
Eventually consistent(最终一致性):系统中的所有副本经过一段时间同步后,最终能够到达一个一致的状态。
最终一致性的:
(1)Causal consistency:即如果一系列写入按某个逻辑顺序发生,那么任何人读取这些写入时,会看见它们以正确的逻辑顺序出现。
(2)Read your writes:进程A更新一个数据项后,它自己总能够访问到更新过后的最新值。
(3)Session consistency:执行更新操作之后,客户端总能够在同一个会话中始终读到该数据项的最新值。
(4)Monotonic read consistency:单调一致性是指如果一个进程从系统中读取一个数据项的某个值后,那么系统对于该进程后续的任何数据访问都不应该返回更旧的值。
(5)单调写一致性:一个系统需要能够保证来自同一个进程的写操作被顺序地执行。
二、 一致性协议
2PC 和 3PC:
背景:当一个事务操作需要跨越多个分布式节点的时候,为了保持事务处理的ACID特性,就需要引入一个称为“协调者”的组件来统一调度分布式节点的执行逻辑,这些被调度的分布式节点则被称为“参与者”。协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务真正的提交。
2PC(二阶段提交协议):
目前,绝大部分的关系型数据库都是采用二阶段提交协议来完成分布式事务的处理,利用该协议能够非常方便的完成所有分布式事务参与者的协调,统一决定事务的提交或回滚,从而有效的保证分布式数据的一致性。
- 阶段一:提交事务请求:
(1)事务询问:协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待参与者的响应。
(2)执行事务:各参与者节点执行事务操作,写redo和undo
(3)各参与者向协调者反馈事务询问的响应(类似投票阶段) - 阶段二:执行事务提交:
(1)执行事务提交,返回ack确认
(2)中断事务提交,回滚
存在的问题:
(1)同步堵塞:各个参与者在等待其他参与者响应的过程中,将无法进行其他操作。
(2)单点问题:一旦协调者出现问题,系统就崩了,出现在阶段二,那么其他参与者都会处于锁定事务资源的状态。
(3)数据不一致:在阶段二发送commit命令时,只有部分参与节点收到
(4)太过保守:2PC没有完善容错机制,任意一个节点的失败都会导致整个事务的失败。
3PC(三阶段提交协议):
是将2PC的“提交事务请求”过程一分为二,形成了CanCommit,PreCommit和 do Commit三个阶段组成的事务处理协议。
- 阶段一:canCommit:确认所有参与者节点是否能够顺利执行事务。
- 阶段二:PreCommit:
(1)执行事务预提交
(2)中断事务 - 阶段三:doCommit:进行事务提交(协调者和参与者失联,参与者在经过等待时间后,继续进行事务的提交)
(1)执行提交
(2)中断事务
优缺点
相对于2PC,3PC最大的优点就是降低了参与者堵塞范围,并且能够在出现单点故障之后继续达成一致。
收到PreCommit之后如果出现网络分区,此时协调者和参与者无法进行正常的网络通信,在这种情况下,该参与者依然会进行事务的提交,这必然导致出现数据的不一致。
Paxos算法:
从整体上来说Paxos算法目标就是保证最终有一个提案会被选定,当提案选定之后,进程最终也能获得被选定的提案。
角色
-
Proposer(提出者):提出提案,一个提案由一个编号及value组成,提案的编号必须全局唯一
-
Acceptor(接收者):决策者,提案的受理者,投票
-
Learner(学习者):备份
Basic Paxos: -
准备阶段:
(1)proposer: 选择一个提案编号Mn,向acceptor的多数派发送编号为Mn的prepare请求。
(2)acceptor:如果接收到编号为Mn 的prepare请求,并且Mn大于它已经回应的任何prepare请求,它就返回已经批准的编号最高的提案的value(如果有的话),并承诺不再批准任何编号小于Mn的提案。 -
接受阶段:
(1)proposer :如果收到了多数acceptor对prepare请求Mn的回应,它就向这些Acceptor发送提案[Mn, Mv]的accept请求,其中Mn是所有prepare请求回应中编号最大的已批准提案的value.
(2)acceptor:如果收到了提案[Mn, Mv]的accept请求,它就批准该提案,除非它已经回应了一个编号大于Mn的提案。
活锁问题
当某一proposer提交的proposal被拒绝时,可能是因为acceptor 承诺返回了更大编号的proposal,因此proposer提高编号继续提交。 如果2个proposer都发现自己的编号过低转而提出更高编号的proposal,会导致死循环,这种情况也称为活锁。
解决方案:
(1)Proposer失败之后给一个随机的等待时间,这样就减少同时请求的可能。
(2)选出一个主proposer,作为提案的唯一人选。
三、Zookeeper
zookeeper可以保证的分布式一致性特性:
- 顺序一致性:从同一个客户端发起的事务请求,最终将会严格地按照其发起顺序被应用到Zookeeper中
- 原子性:所有事务请求的处理结果在整个集群的所有机器上应用情况是一致的。
- 单一视图:无论客户端连接的是哪一个zookeeper服务器,其看到的服务端数据模型都是一致的。
- 可靠性:一旦服务端成功应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会被一直保留下来,除非有另一个事务又对其进行了变更。
- 实时性:zookeeper仅仅保证在一定的时间段内,客户端最终一定能够从服务端读取最新的数据状态。
ZAB协议(原子消息广播协议)
Zookeeper 使用一个单一的主进程来接收并处理客户端所有事务请求,并采用ZAB的原子广播协议,将服务器数据的状态变更以事务Proposal的形式广播到所有的副本进程上去。
主要流程:
所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为Leader服务器,而余下的服务器则成为Follower服务器。Leader服务器负责将一个客户端事务请求转换为一个事务 Proposal(提议),并将Proposal分发给集群中所有的Follower服务器。之后Leader服务器需要等待所有Follower服务器的反馈,一旦超过半数,那么Leader就会再次向所有的Follower服务器分发Commit消息,要求对前一个Proposal进行提交。
协议介绍:
流程
- 崩溃恢复:当整个服务重启或者leader崩溃等异常情况,ZAB协议就会进入恢复模式并选举产生新的Leader服务器。当选举了新的Leader服务器,同时集群中已经有过半的机器与该Leader服务器完成了状态同步之后,ZAB就退出恢复模式。然后进行消息广播模式
- 消息广播:当一台同样遵循ZAB协议的服务器启动后加入到集群中时,如果此时集群中已经存在一个Leader服务器复杂进行消息广播,那么新加入的服务器就会自觉的进行数据恢复模式:找到lead所在的服务器,并与其进行数据同步,然后一起参与到消息广播中。
消息广播(类似2PC)
只要半数通过,就可以提交事务。
- 处理Leader崩溃的情况导致数据不一致问题------崩溃恢复模式
- 广播协议是基于具有FIFO特性的TCP协议来进行网络通信的,因此能够很容易地保证消息广播过程中消息接收与发送的顺序性。
- 为每个事务分配一个全局单调递增的唯一ID(ZXID)
崩溃恢复
解决消息广播过程中出现leader崩溃等异常
特殊情况:
(1)崩溃恢复过程需要确保已经被Leader提交的Proposal也能够被所有的Follower提交。
(2)ZAB协议需要确保丢弃那些只在Leader服务器上被提出的事务
针对上述情况:
ZAB协议必须设计这样一个Leader选举算法:
(1)能够确保提交已经被leader提交事务的Proposal
(2)同时丢弃已经被跳过的事务的proposal.
针对这一要求,让Leader选举算法能够保证新选举出来的Leader服务器拥有集群中所有机器最高编号(ZXID最大)的事务Proposal,那么就可以保证这个新选举出来leader一定具有所有已经提交的提案。
leader选举成功后要进行数据同步:
在正式工作开始之前,要确认Leader服务器确认事务日志中所有Proposal是否已经被集群中过半机器提交了。Leader服务器会为每一个Follower服务器都准备一个队列,并将那些没有被各Follower服务器同步的事务以Proposal消息的形式逐个发个Follower服务器,并在每个Proposal服务器后面紧跟commit。
ZXID
一个64位数字,其中低32位可以看做是一个简单的单调递增的计数器,针对客户端的每个事务请求,Leader服务器在产生一个新的事务Proposal的时候,都会对该计数器进行加1操作;而高32位则代表Leader周期epoch编号,Leader服务器从本地取出本地日志中最大事务ZXID,并从ZXID中解析出epoch,然后进行加1 ,低32 置0.
zookeeper的系统模型
- 节点类型
(1)持久节点
(2)临时节点
(3)顺序节点 - watch机制:
Watch机制主要包括客户端线程、客户端WatchManager 和 ZooKeeper服务器三部分。客户端在向Zookeeper服务器注册Watcher的同时,会将Watcher对象存储在客户端的WatchManager中。当Zookeeper服务器触发Watcher事件后,会向客户端发送通知,客户端线程从Watchmanager中取出对应的Watcher对象来执行回调逻辑。
服务器启动时期的选举:
- 每个Server会发出一个投票(myid,ZXID),然后将这个投票发给集群中所有其他机器
- 接收来自各个服务器的投票
- 处理投票:针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK
- 统计投票
- 改变服务器状态
服务器运行期间的选举
- 变更状态:当Leader挂了之后,Follower变更自己的状态为Locking,然后开始进入leader选举
- 和启动时一样