老刘是一名即将找工做的研二学生,写博客一方面是复习总结大数据开发的知识点,一方面是但愿可以帮助和本身同样自学编程的伙伴。因为老刘是自学大数据开发,博客中确定会存在一些不足,还但愿你们可以批评指正,让咱们一块儿进步!算法
今天给各位小伙伴聊聊分布式系统的数据一致性问题,这个必定要从服务器架构部署的发展历程讲起!文章篇幅较长,请你们耐心观看,精彩千万不要错过!编程
首先要讲的是集中式服务,那集中式是什么?就是事情都由一台服务器搞定。安全
而集中式系统就是由一台或多台主计算机组成中心节点,数据集中存储于这个中心节点中,而且整个系统的全部业务都在这个中心节点上,系统全部的功能都由它作。服务器
也就是说,在集中式系统中,每一个客户端仅仅负责数据的输入和输出,而数据的存储与控制处理彻底交给主机完成。网络
那集中式服务优势:架构
可是它的缺点也是很是明显:并发
什么是摩尔定律?分布式
摩尔定律是由英特尔(Intel)创始人之一戈登·摩尔(Gordon Moore)提出来的。其内容为:当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增长一倍,性能也将提高一倍。换言之,每一美圆所能买到的电脑性能,将每隔18-24个月翻一倍以上。摘自:百度百科高并发
摩尔定律告诉咱们:纵向扩展理论上是受限的,因此只能考虑横向扩展,并且从理论上说,横向扩展理论上是不受限的!性能
那既然纵向扩展受限,咱们就去尝试横向扩展,就有了分布式!
分布式意味着能够采用更多的普通计算机(相对于昂贵的大型机)组成分布式集群对外提供服务。计算机越多,CPU、内存、存储资源等也就越多,可以处理的并发访问量也就越大。
例如一个由分布式系统实现的电子商城,在功能上可能被拆分红多个应用,分别提供不一样的功能,组成一个分布式系统对外提供服务。
因此,分布式系统中的计算机在空间上是几乎没有限制的,这些计算机可能被放在不一样的机柜上,也可能被部署在不一样的机房中,还可能在不一样的城市中。
和集中式系统相比,分布式系统的性价比更高、处理能力更强、可靠性更高、也有很好的扩展性。
可是,分布式解决了网站的高并发问题的同时也带来了一些其余问题。
首先,分布式的必要条件就是网络,这可能对性能甚至服务能力形成必定的影响。其次,一个集群中的服务器数量越多,服务器宕机的几率也就越大。另外,因为服务在集群中分布式部署,用户的请求只会落到其中一台机器上,因此,一旦处理很差就很容易产生数据一致性问题。
一、通讯异常:网络不可用(消息延迟或者丢失),会致使分布式系统内部没法顺利进行网络通讯,因此可能形成多个节点数据丢失和状态不一致,还有可能形成数据乱序。
二、网络分区:网络不连通,但各个子网络的内部网络是正常的,从而致使整个系统的网络环境被切分红若干个孤立的区域,分布式系统就出现了局部小集群形成的数据不一致。
三、节点故障:服务器节点出现的宕机的现象。
四、存储数据丢失:对于有状态节点来讲,数据丢失意味着状态丢失,一般只能从其余节点读取、恢复存储的状态。解决方案:利用多副本机制。
一、性能:这是一个很是让人头疼的问题,追求高吞吐的系统,每每很难作到低延迟;系统平均响应时间较长时,也很难提升QPS。
系统的吞吐能力,指系统在某一时间能够处理的数据总量,一般能够用系统每秒处理的总数据量来衡量; 系统的响应延迟,指系统完成某一功能须要使用的时间; 系统的并发能力,指系统能够同时完成某一功能的能力,一般也用QPS来衡量。
二、可用性:系统的可用性(availability)指系统在面对各类异常时能够正确提供服务的能力。可用性是分布式的重要指标,衡量了系统的鲁棒性,是系统容错能力的体现。
三、可扩展性:系统的可扩展性(scalability)指分布式系统经过扩展集群机器规模提升系统性能(吞吐、延迟、并发)、存储容量、计算能力的特性。
四、一致性:分布式系统为了提升可用性,老是不可避免地使用副本的机制,从而引起副本一致性的问题。
例如,就是一份数据存在分布式系统,存在多个不一样的节点当中存着相同的数据。若是多个不一样的节点存的数据不同,多个客户端去访问的时候就会存在这种状况,第1个客户端去访问的结果为A,第2个客户端访问的结果为B,两个客户端访问获得不一样的结果,那就是一致性作的很差。
说了这么多,咱们若是设计一个优秀的分布式系统,它应该具备这些特色:吞吐高、响应延迟低、并发强、可用性很高、可扩展性很强、一致性很好。但并非每一个特色都能知足,有几个特色是相互矛盾的,须要咱们想办法克服!
而在分布式场景中真正复杂的是数据一致性的问题!
一致性也分不少种,这里说说老刘了解的三个。
强一致性:写操做完成以后,读操做必定能读到最新数据。通俗地讲就是客户端只要把结果写进去了,何时访问都能拿到最新的数据。可是在分布式场景中很难实现,后续的Paxos 算法,Quorum 机制,ZAB 协议等能实现!
弱一致性:不保证拿到最新的数据,也有可能拿到旧的数据。
最终一致性:不考虑中间的任何状态,只保证通过一段时间以后,最终系统内数据正确。在高并发场景中,它也是使用最广的一致性模型。
说了那么多分布式一致性的内容,那它的做用是什么呢?
一、为了提升系统的可用性,通常都会使用多副本机制,多副本就会有分布式一致性的问题,它就是为了提升系统的可用性,防止单点节点故障引发的系统不可用。
二、提升系统的总体性能,数据分布在集群中多个节点上,它们都能为用户提供服务。
老刘说了这么多,你们有没有猜到想引出什么内容呢?
上述那么多内容只为引出分布式系统的数据一致性问题!咱们用来解决分布式系统的数据一致性问题的方案有以下:
分布式事务+事务 分布式一致性算法 Quorum机制 CAP和BASE理论
分布式系统中,每一个节点都能知道本身的事务操做是否成功,可是无法知道系统中的其余节点的事务是否成功。这就有可能会形成分布式系统中的各节点的状态出现不一致。所以当一个事务须要跨越服务器节点,而且要保证事务的ACID特性时,就必须引入一个协调者的角色。那么其余的各个进行事务操做的节点就都叫作参与者。
现实生活中有两种典型的分布式事务的提交模式:2PC和3PC。
直接上图:
我让A去作一件事,让B去作另一件事,而且这两件事在一个分布式事务中要保证同时成功或失败。那如何作到数据一致呢?
2PC分两个阶段: 第一阶段:执行事务,但不提交。 第二阶段:当协调者收到第一阶段中全部事务参与者的正反馈时(事务都执行成功了), 就去发命令让全部参与者提交事务。
看了2PC的两个提交阶段和图,有经验的人一眼就会看出里面存在的问题。
1 阻塞问题
协调者发送命令给参与者,因为是网路发送命令,就会存在不一样参与者收到的命令有前后、有延迟。例如参与者A很快就收到了,参与者B网络有问题,过了好久才收到命令。参与者A很快处理完发送反馈, 而参与者B就好久以后才发送反馈,致使协调者等待时间特别长。 这就是一个很是典型的阻塞问题,很是浪费资源,影响性能!
2 没有容错机制,存在单点故障问题
事务协调者是整个分布式事务的核心,一旦协调者出现故障,看看上面那张图,就会知道参与者就收不到 commit/rollback的通知,从而致使参与者节点一直处于事务没法完成的中间状态。
3 数据不一致
在第二阶段,若是发生局部网络问题,一个参与者收到提交的命令,另外一个参与者没有收到提交的命令, 就会形成节点间数据不一致。
3PC就是三阶段提交的意思,它是2阶段提交的改进版,把二阶段提交协议的 "提交事务请求" 一分为二,造成了cancommit,precommit,docommit 三个阶段。
除了在 2PC 的基础上增长了CanCommit阶段,还引入了超时机制。一旦事务参与者在指定时间内没有收到协调者的 commit/rollback 指令,就会自动本地 commit,这样能够解决协调者单点故障的问题。
第一阶段:CanCommit阶段
在第一阶段准备的时候,先问一下各个参与者是否能够进行事务操做以及超时机制,参与者在必定时间没 收到协调者的指令会自动提交。
第二阶段:PreCommit阶段
一、若是每一个参与者返回的都是赞成,协调者则向全部参与者发送预提交请求,并进入预提交阶段; 二、参与者收到预提交请求后,执行事务操做。 三、参与者执行完本地事务以后,会向协调者发出Ack表示已准备好提交,并等待协调者下一步指令。 四、若是协调者收到预提交响应为拒绝或者超时,则执行中断事务操做,通知各参与者中断事务。 五、参与者收到中断事务或者等待超时,都会主动中断事务/直接提交
第三阶段:doCommit阶段
一、协调者收到全部参与 的Ack,则从预提交入提交段,并向各参与者发送提交请求。 二、参与者收到提交请求,正式提交事务(commit),并向协调者反馈提交结果Y/N。 三、协调者收到全部反馈消息,完成分布式事务。 四、若是协调者超时没有收到反馈,则发送中断事务指令。 五、参与者收到中断事务指令后,利用事务日志进行rollback。 六、参与者反馈回滚结果,协调者接收反馈结果或者超时,完成中断事务。
3PC也可能出现数据不一致,第三阶段让全部参与者回滚事务,但有一个参与者在规定的时间内没有收到,它会默认进行提交操做,就会出现数据不一致。因为网络问题,第二阶段到第三阶段之间特别容易出现数据不一致问题。
在2PC和3PC的原理上,优秀的开发者们实现了分布式一致性算法,这里老刘先大体讲讲Poxos算法和ZAB协议的相关概念。若是想详细了解Paxos算法和ZAB协议,等老刘找完工做后,专门写一篇Zookeeper源码文章。
Paxos 算法使用一个希腊故事来描述,在 Paxos 中,存在三种角色,分别为
一、Proposer(提议者,用来发出提案proposal), 二、Acceptor(接受者,能够接受或拒绝提案), 三、Learner(学习者,学习被选定的提案,当提案被超过半数的Acceptor接受后为被批准)。
映射到 zookeeper 集群:
leader:发起提案 主席(单点故障的解决办法是leader选举机制) follower:参与投票 人大表明 observer:被动接受 全国全部人
以及有一个特别出名的机制:议会制
保证超过半数达成一致性便可的协议
总结下Paxos算法,它就是全部事务请求必须由一个全局惟一的服务器来协调处理,这样的服务器被称为 leader 服务器,而余下的其余服务器则成为 follower 服务器。
leader 服务器负责将一个客户端事务请求转换成一个事务proposal,并将该 proposal 分发给集群中全部的follower 服务器。以后 leader 服务器须要等待全部follower 服务器的反馈,一旦超过半数的 follower 服务器进行了正确的反馈后,那么 leader 就会再次向全部的 follower 服务器分发 commit 消息,要求其将前一个 proposal 进行提交。
ZooKeeper的底层工做机制,就是依靠 ZAB 实现的。它实现了崩溃回复和消息广播两个主要功能。
ZAB协议保证数据一致性的两个重要特色就是:
一、ZAB协议须要确保那些已经在 leader 服务器上提交的事务最终被全部服务器都提交。
二、ZAB协议须要确保丢弃那些只在 leader 服务器上被提出的事务。
为了解决单点故障,有leader选举算法。在leader选举中,若是让 leader 选举算法可以保证新选举出来的 leader 服务器拥有集群中全部机器最高事务编号(ZXID)的事务proposal,那么就能够保证这个新选举出来的 leader 必定具备全部已经提交的提案。
由于事务的每次执行都会有一个编号,最高事务编号表明着最新的事务,即最新的数据。 根据上述ZAB协议内容,ZooKeeper实现了分布式系统数据的一致性!
简单描述:如有n个笼子和n+1只鸽子,全部的鸽子都被关在鸽笼里,那么至少有一个笼子有至少2只鸽子 。
Quorum NWR:Quorum 机制是分布式场景中经常使用的,用来保证数据安全,而且在分布式环境中实现最终一致性的投票算法。这种算法的主要原理来源于鸽巢原理。它最大的优点,既能实现强一致性,并且还能自定义一致性级别!
N:总节点数
W:总写入成功数
R:总读取数
当W+R>N时,必定能保证读到最新的数据,即强一致性! 为何这样说?
如上图,有4个箱子,3个箱子里面有东西,那如何保证必定能拿到有数据的箱子?最起码拿2个箱子就能拿到有东西的箱子!
就是利用这种原理,只要保证(W + R > N)就必定能读取到最新的数据,数据一致性级别彻底能够根据读写副本数的约束来达到强一致性!
那如今分如下三种状况讨论:前提是N已经肯定不改了!
W = 1, R = N,Write Once Read All
在分布式环境中,写一份,至关于只有只有一个箱子有东西,那么若是要读取到最新数据,即拿到有东西的箱子,就必需要读取全部节点,而后取最新版本的值了。写操做高效,可是读操做效率低。一致性高,但分区容错性差,可用性低。
W = N,R = 1, Read Only Write All
在分布式环境中,全部节点都同步完毕,才能读取,因此只要读取任意一个节点就能够读取到最新数据。读操做高效,可是写操做效率低。分区容错性好,一致性差,实现难度更高,可用性高 。
W = Q, R = Q where Q = N/2 + 1
能够简单理解为写超过一半节点,那么读也超过一半节点,取得读写性能平衡。通常应用适用,读写性能之间取得平衡。如 N=3, W=2, R=2,分区容错性,可用性,一致性取得一个平衡。
ZooKeeper就是这么干的!采用了第三种状况!
根据上述说的,作到强一致性了,就难作到高可用,二者是很是矛盾的。因此CAP理论就告诉咱们,一个分布式系统不可能同时知足C,A,P三个需求。
C:Consistency,强一致性
分布式环境中多个数据副本保持一致
A:Availability,高可用性
系统提供的服务必须一直处于可用,对于用户的每个操做请求老是能在有限时间内返回结果
P:Partiton Tolerance 分区容错性
分布式系统在遇到任何网络分区故障时,仍然须要可以保证对外提供知足一致性和可用性的服务
既然一个分布式系统不能同时知足C,A,P三个需求,那么如何选择?
CAP只能3选2,由于在分布式系统中,容错性P确定是必须有的,因此这时候无非就两种状况,网络问题致使要么错误返回,要么阻塞等待,前者牺牲了一致性,后者牺牲了可用性。
对于单机软件,由于不一样考虑P,因此确定是CA型,好比MySQL。
对于分布式软件,由于必定会考虑P,因此又不能兼顾A和C的状况下,只能在A和C作权衡,好比HBase、Redis等。作到服务基本可用,而且数据最终一致性便可。 因此,就产生了BASE理论。
多数状况下,其实咱们也并不是必定要求强一致性,部分业务能够容忍必定程度的延迟一致,因此为了兼顾效率,发展出来了最终一致性理论 BASE,它的核心思想是:即便没法作到强一致性,但每一个应用均可以根据自身业务特色,采用适当的方式来使系统达到最终一致性。
一句话就是作事别走极端,BASE 是对 CAP 理论中的 C 和 A 进行权衡获得的结果。
BASE理论作到的不是强一致,而是最终一致;不是高可用,而是基本可用。
Basically Available(基本可用):基本可用是指分布式系统在出现故障的时候,容许损失部分可用性,保证核心可用。 例如:淘宝双11,为保护系统稳定性,正常下单,其余边缘服务可暂时不可用。
Eventually Consistent(最终一致):最终一致性是指系统中的全部数据副本通过必定时间后,最终可以达到一致的状态。
之后开发分布式系统,就能够根据业务来决定到底追求高可用仍是追求强一致性!
好啦,分布式系统的数据一致性问题大体聊得差很少了,老刘主要给你们讲了讲分布式系统一致性的背景以及实现。尽管当前水平可能不及各位大佬,但老刘仍是但愿可以变得更加优秀,可以帮助更多自学编程的伙伴。
若是有相关问题,请联系公众号:努力的老刘,和老刘进行愉快的交流,若是以为帮到了您,不妨点赞关注支持一波!