一.分布式系统的一致性概述
1.一致性的重要性
分布式领域的CAP理论告诉我们,任何一个分布式系统都无法同时满足Consistency(一致性),Availability(可用性), Partition tolerance(分区容错性) 这三个基本需求。最多只能满足其中两项。
但是,一个分布式系统无论在CAP三者之间如何权衡,都无法彻底放弃一致性(Consistency),如果真的放弃一致性,那么就说明这个系统中的数据根本不可信,数据也就没有意义,那么这个系统也就没有任何价值可言。所以,无论如何,分布式系统的一致性问题都需要重点关注。
而通常情况下,我们所说的分布式一致性问题通常指的是数据一致性问题。
数据一致性其实是数据库系统中的概念。我们可以简单的把一致性理解为正确性或者完整性,那么数据一致性通常指关联数据之间的逻辑关系是否正确和完整。我们知道,在数据库系统中通常用事务(访问并可能更新数据库中各种数据项的一个程序执行单元)来保证数据的一致性和完整性。而在分布式系统中,数据一致性往往指的是由于数据的复制,不同数据节点中的数据内容是否完整并且相同。
比如在集中式系统中,有一些关键的配置信息,可以直接保存在服务器的内存中,但是在分布式系统中,如何保存这些配置信息,又如何保证所有机器上的配置信息都保持一致,又如何保证修改一个配置能够把这次修改同步到所有机器中呢?
再比如,在集中式系统中,进行一个同步操作要写同一个数据的时候,可以直接使用事务+锁来管理保证数据的ACID。但是,在分布式系统中如何保证多台机器不会同时写同一条数据呢?
2.为什么会有数据一致性问题
虽然分布式系统有着诸多优点,但是由于采用多机器进行分布式部署的方式提供服务,必然存在着数据的复制。分布式系统的数据复制需求主要来源于以下两个原因:
可用性。将数据复制到分布式部署的多台机器中,可以消除单点故障,防止系统由于某台(些)机器宕机导致的不可用。
性能。通过负载均衡技术,能够让分布在不同地方的数据副本全都对外提供服务,有效提高系统性能。
在分布式系统引入复制机制后,不同的数据节点之间由于网络延时等原因很容易产生数据不一致的情况。复制机制的目的是为了保证数据的一致性。但是数据复制面临的主要难题也是如何保证多个副本之间的数据一致性。
假设有这样的场景,有两个人同时去两个不同的火车站买票(A去A火车站,B去B火车站),为了保证合理的卖票,需要在A火车站和B火车站之间共享关于剩余票数的数据。但是A和B要买的票只剩下一张。一张票当然只能卖给一个人。 如果为了保证系统性能,那么A和B在买票的时候应该都可以买票成功(因为他们在买票过程中余票数据都显示还有一张余票)。两人在买完票之后,系统在做数据复制时发现一张票被卖出了两次,这时就要让A和B两人其中一人手中得票作废掉。这时就要花费很大的力气来通知后买到这张票的人这个消息。。。 如果为了保证数据一致性,那么就需要在A买票的过程中,B只能等着。等A买票结束,并且把余票结果同步到B火车站的售票窗口。然后B才能知道还有没有余票可以购买。
上面的例子可以简单的说明一个系统如果想保证数据一致性很有可能影响其性能。因为并发的写请求需要在前一个写请求结束之后才能进行。
因此,如何能既保证数据一致性,又保证系统的性能,是每一个分布式系统都需要重点考虑和权衡的。一致性模型可以在做这些权衡的时候给我们很多借鉴和思考。
3.一致性模型
3.1强一致性
当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这对用户是最友好的,就是用户上一次写什么,下一次就保证能读到什么,但是这种实现对性能影响较大。
3.2弱一致性
系统并不保证后续进程或者线程的访问都会返回最新的更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。但会尽可能保证在某个时间级别(比如秒级别)之后,可以让数据达到最终一致性状态。
3.3最终一致性
弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。DNS是一个典型的最终一致性系统。
补充:最终一致性模型的变种
因果一致性:如果A进程在更新之后向B进程通知更新的完成,那么B的访问操作将会返回更新的值。如果是没有因果关系的C进程将会遵循最终一致性的规则。
读己所写一致性:因果一致性的特定形式。一个进程总可以读到自己更新的数据。
会话一致性:读己所写一致性的特定形式。进程在访问存储系统同一个会话内,系统保证该进程读己之所写。
单调读一致性:如果一个进程已经读取到一个特定值,那么该进程不会读取到该值以前的任何值。
单调写一致性:系统保证对同一个进程的写操作串行化。
上述最终一致性的不同方式可以进行组合,例如单调读一致性和读己之所写一致性就可以组合实现。并且从实践的角度来看,这两者的组合,读取自己更新的 数据,和一旦读取到最新的版本不会再读取旧版本,对于此架构上的程序开发来说,会少很多额外的烦恼。
二.CAP理论
一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)中的两项。
1.1 Consistency一致性
一致性指“all nodes see the same data at the same time”,即更新操作成功并返回给客户端后,所有节点在同一时间的数据完全一致。
对于一致性,可以分为从客户端和服务端两个不同的视角。从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致。一致性是因为有并发读写才有的问题,因此在理解一致性的问题时,一定要注意结合考虑并发读写的场景;
从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性。对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。如果能容忍后续的部分或者全部访问不到,则是弱一致性。如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。
1.2 Availability可用性
可用性指“Reads and writes always succeed”,即服务一直可用,而且是正常响应时间。
对于一个可用性的分布式系统,每一个非故障的节点必须对每一个请求作出响应。也就是该系统使用的任何算法必须最终终止。当同时要求分区容忍性时,这是一个很强的定义:即使是严重的网络错误,每个请求必须终止。
好的可用性主要是指系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。可用性通常情况下可用性和分布式数据冗余,负载均衡等有着很大的关联;
1.3 Partition Tolerance分区容错性
分区容错性指“the system continues to operate despite arbitrary message loss or failure of part of the system”,即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。
分区容错性和扩展性紧密相关。在分布式应用中,可能因为一些分布式的原因导致系统无法正常运转。好的分区容错性要求能够使应用虽然是一个分布式系统,而看上去却好像是在一个可以运转正常的整体。
比如现在的分布式系统中有某一个或者几个机器宕掉了,其他剩下的机器还能够正常运转满足系统需求,或者是机器之间有网络异常,将分布式系统分隔未独立的几个部分,各个部分还能维持分布式系统的运作,这样就具有好的分区容错性;
2.CAP权衡
通过CAP理论,我们知道无法同时满足一致性、可用性和分区容错性这三个特性,那要舍弃哪个呢?
CAwithoutP:如果不要求P(不允许分区),则C(一致性)和A(可用性)是可以保证的。但其实分区不是你想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各子系统依然保持CA;
CPwithoutA:如果不要求A(可用性),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式;
APwihtoutC:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类;
总结:
对于多数大型互联网应用的场景,主机众多、部署分散,而且现在的集群规模越来越大,所以节点故障、网络故障是常态,而且要保证服务可用性达到N个9,即保证P和A,舍弃C(退而求其次保证最终一致性)。虽然某些地方会影响客户体验,但没达到造成用户流程的严重程度。
对于涉及到钱财这样不能有一丝让步的场景,C必须保证。网络发生故障宁可停止服务,这是保证CA,舍弃P。还有一种是保证CP,舍弃A。例如网络故障事只读不写。
孰优孰略,没有定论,只能根据场景定夺,但是唯一确定的是如果想增强任意两个的性能,只能降低第三个的性能来实现。
三.BASE理论
BASE理论是对CAP理论的延伸,核心思想是即使无法做到强一致性(Strong Consistency,CAP的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)。
BASE是指基本可用(Basically Available)、软状态( Soft State)、最终一致性( Eventual Consistency)。
1.基本可用(Basically Available)
基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。
比如电商大促销时,为了应对访问量激增,部分用户可能会被引导到降级页面,服务层也可能只提供降级服务。这就是损失部分可用性的体现。
2.软状态(Soft State)
软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时就是软状态的体现。mysql replication的异步复制也是一种体现。
3.最终一致性(Eventual Consistency)
最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。
4.ACID和BASE的区别与联系
ACID是传统数据库常用的设计理念,追求强一致性模型。BASE支持的是大型分布式系统,提出通过牺牲强一致性获得高可用性。
ACID和BASE代表了两种截然相反的设计哲学,在分布式系统设计的场景中,系统组件对一致性要求是不同的,因此ACID和BASE又会结合使用。
四.分布式一致性算法paxos
为了解决分布式的一致性问题,在长期的研究探索过程中,涌现出了一大批经典的一致性协议和算法,其中比较著名的有二阶段提交协议,三阶段提交协议和Paxos算法。
关于二阶段和三阶段提交协议的说明:
http://blog.chinaunix.net/uid-30212356-id-5731591.html
4.1来源背景
Paxos算法是莱斯利·兰伯特于1990年提出的一种基于消息传递的一致性算法。为描述Paxos算法,Lamport讲述了这样一个故事:
在古希腊有一个岛屿叫做Paxos,这个岛屿通过议会的形式修订法律。执法者(legislators,后面称为牧师priest)在议会大厅(chamber)中表决通过法律,并通过服务员传递纸条的方式交流信息,每个执法者会将通过的法律记录在自己的账目(ledger)上。问题在于执法者和服务员都不可靠,他们随时会因为各种事情离开议会大厅、服务员也有可能重复传递消息(或者直接彻底离开),并随时可能有新的执法者(或者是刚暂时离开的)回到议会大厅进行法律表决,因此,议会协议要求保证上述情况下可以能够正确的修订法律并且不会产生冲突,即上述情况不会发生的情况下;
4.2paxos解决了什么问题
分布式的一致性问题其实主要是指分布式系统中的数据一致性问题。所以,为了保证分布式系统的一致性,就要保证分布式系统中的数据是一致的。
在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。所以,paxos算法主要解决的问题就是如何保证分布式系统中各个节点都能执行一个相同的操作序列。
4.3paxos算法解释
用三国反穿越剧描述Paxos:
http://blog.csdn.net/russell_tao/article/details/7244530
英文文档(带演示):
http://harry.me/blog/2014/12/27/neat-algorithms-paxos/
paxos视频:
知乎回答:
文章参考来源:
http://my.oschina.net/foodon/blog/372703?fromerr=LVfucULf