分布式系统的一些基础理论
前言
我们先简单了解下什么是分布式系统。在《分布式系统概念与设计》一书中,对分布式系统做了如下定义:
分布式系统是一个硬件与软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统。
分布性
分布式系统中的多态计算机在空间上可以随意分布,分布情况也可以随时变动。
对等性
分布式系统中的节点没有主从之分,都是对等的。副本(Replica)是分布式系统最常见的冗余手段。
并发性
分布式系统中并发性操作是正常的常见行为,如何准确、高效地协调分布式并发操作,是分布式系统架构与设计中最大的挑战。
挑战
故障与部分失效
不可靠的网络
不可靠的时钟
数据一致性与可用性的平衡
ACAD
ACID 是指数据库在写入或更新数据时,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。
ACAD主要用于本地事务处理或者是集中式的事务处理系统,这里提出来只是做一个前置概念,具体细节不再赘述。
随着分布式事务的出现,传统的单机事务模型已经无法胜任。尤其是对于一个高访问量、高并发的互联网分布式系统来说,如果我们期望实现一套严格满足ACAD特性的分布式事务,很可能出现的情况就是在系统的可用性和强一致性之间出现冲突。所以才有了后续的CAP与BASE这些分布式系统经典理论。
CAP
Eric Brewer教授提出了一个著名的CAP理论:一致性(Consistency),可用性(Availability)以及分区容忍性(Partition tolerance)三者不能同时满足。
后续说的一致性,没有特殊说明都是指强一致性。
一致性
读操作能返回最新的写操作。对于分布式存储系统,某个节点更新数据,其他节点如果能读取到这个最新的数据,那么就称为强一致。
可用性
在合理的时间内返回合理的响应。返回错误结果、请求超时、自定义性能不达标,都是不可用的。
分区容忍性
出现网络分区节点故障,系统能够继续正常工作。无论是业务数据分片还是人物分片,节点之间要网通通讯,就可能存在网络超时(Connnection Time Out)或网络中断读超时(Socket Time Out)。
误区
CAP三者的关系
对于CAP理论,在工作中发现大家对其有误解:认为这三个因素是对等的,可以三选二,只要牺牲了另一个就可以满足另外2个。
在大规模分布式系统下,P(分区可用性)是必然存在的事实,只能在C和A之间权衡。
CP系统最求强一致性,比如Zookeeper,但牺牲了一定的性能与可用性。
AP系统追求高可用,牺牲了一定的一致性,比如数据库的主从复制、kafka的主从复制。
我们首先来看为什么很少有CA的系统。
业务要实现A(高可用),必然需要冗余,有了冗余就会有P(网络分区),比如传统的关系数据库实现了事务的ACID,也就是C(强一致性),但是单机版没有A(高可用)也没有P(分区可用性),要实现A(高可用),需要加从库,也只解决了A(高可用)的问题,但是又破坏了C(一致性),只能寻求最终一致性。
通过上面的分析可以看出,P(分区可用性)并不是可以通过牺牲C(强一致性)或者A(高可用)换取的,而是要通过网络基础设施的稳定性来保证,而网络基础设施只能通过强大的网络工程能力来保证,在最大限度地保证P的情况下,再考虑同时达到C(强一致性)和A(高可用)。
但存在一个关键问题:即使保证了P,网络完全健康,没有分区,但信息传输也需要时间,所以“延时”不可避免。
真正的强一致性不存在
不管信息变化的时间有多短、传播有多快,从客观的微观角度来看,世界永远是不一致的,就好像没有永动机一样。
信息的传播需要「时间」,有「时间」就会有「延时」,有「延时」就会有不一致。
信息所反映的客观世界在变化,也就意味着信息「状态」随时会「过时」。
信息传递的通道是不可靠的,软件故障、硬件故障、网络故障都是客观存在的。
从以上三点可以得到结论:客观的强一致性不存在。而我们通常说的「强一致性」,是从观察者的角度得来的。
就好像单机版的MySQL,其强一致性也只是对外屏蔽了内部的「不一致性」,所以客户端看到的「强一致性」,但是内部其实是「最终一致性」(我正在写一系列MySQL的文章,有时间会详细介绍给出链接)。
ACAD与CAP的C
CAP 定理中的一致性与 ACID 数据库事务中的一致性截然不同。
ACID 的 C 指的是事务不能破坏任何数据库规则,如键的唯一性。与之相比,CAP 的 C 仅指单一副本这个意义上的一致性。CAP 的 C 仅指单一副本这个意义上的一致性,因此只是 ACID 一致性约束的一个更高层次的子集。
所以,抛开二者之间「一致性」粒度含义不同,我一般是理解为:ACID是CAP里面的CA实现,有不同看法的欢迎留言实现。
CAP理论脱离实际场景没有价值
我私下里把这类理论称之为「意识流」思想,需要当战略思维而非战术思维来用,否则反而会约束系统设计的思路(跟上面的CAP三者关系的误区有点类似)。
比如一致性,必须要明确一致性的范围,即在一定的边界内状态是一致的(再次确认上面说的没有正在的强一致),超出边界之外的一致性是无从谈起的。
现在很多的分布式文件系统,会采用quorum-vote并行多写、管道复制、主从复制等方式,进行多写,但是是允许部分节点失败的,然后通过类似Last-Add-Confirmed (LAC)的方式来保证读者之间的数据「强一致性」。
虽然有节点写失败了(不一致),但是在整个系统来看,读者面对的是「强一致」的数据。
类似的还有可用性,可用性的衡量标准,也是需要根据具体场景来的。简单的认为某个算法是满足可用性要求其实并不严谨,因为在系统实现过程中会有很多的技巧去弥补修正。
在现实世界中,我们一般不会去追求完美的可用性,所以一般的说法是高可用,即尽可能保证更多的节点服务可用。这也是为什么 Paxos 这类的一致性算法越来越流行的原因之一。
BASE
Eric Brewer(没错,跟CAP是同一个人发表的)在1997发表的论文 Cluster-Based Scalable Network Services 中第一次提出 BASE 的概念。
eBay的架构师Dan Pritchett 在 2008 年发表文章 BASE: An AcidAlternative 中第一次明确提出的 BASE 理论。
BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的简写。
BASE是对CAP中C(一致性)和A(可用性)权衡的结果,其来源于对大规模互联网系统分布式实践的总结,是基于CAP定理逐步演化而来的,其核心思想是即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。
基本可用
基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性:
响应时间上的损失
功能上的损失(降级页面)
弱状态
弱状态也称为软状态,和硬状态相对,是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
最终一致性
最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
分布式事务
分布式方案在网上一搜一大把,2PC、3PC、Saga、MQ、TCC等等。
但是,这篇文章,我主要是想说下:一定要明确是否真的需要分布式事务!!!
出现分布式事务的一个比较多的原因是微服务过多。我见过太多团队一个人维护几个微服务,太多团队过度设计,搞得所有人疲劳不堪,而微服务过多就会引出分布式事务,这个时候我不会建议你去采用下面任何一种方案,而是请把需要事务的微服务聚合成一个单机服务,使用数据库的本地事务。因为不论任何一种方案都会增加你系统的复杂度,这样的成本实在是太高了,千万不要因为追求某些设计,而引入不必要的成本和复杂度。
总结
当系统中存在分区,不应该盲目地牺牲一致性或可用性。通过细致地管理分区期间的不变性约束,两方面的性质都可以取得最佳的表现。
BASE理论是CAP的延伸。BASE理论面向的是大型高可用可扩展的分布式系统,和传统事务的ACID特性是相反的,它完全不同于ACAD的强一致性模型,而是通过牺牲强一致性来获得可用性,只保证最终一致性。而在实际的分布式场景中,不同业务单元和组件对数据的一致性要求是不一样的,因此在具体的分布式系统架构设计过程中,ACID与BASE往往又会结合在一起使用。
对理论的讨论就到这里为止,但是从理论到实践的落地还有很多工作要做。引入 CAP 实践毕竟不像引入 ACID 事务那么简单,实施的时候需要对过去的策略进行全面的考虑,最佳的实施方案极大地依赖于具体服务的不变性约束和操作细节。多研究现有的优秀分布式系统,分析其设计理念和对 CAP 的实现,可以更快地成长。
版权声明: 本文为 InfoQ 作者【俊俊哥】的原创文章。
原文链接:【http://xie.infoq.cn/article/4f80016f680669d59e729b12f】。文章转载请联系作者。
评论