深圳克林斯曼 2020-05-07
0.写在前面
前几天在pyq发起了约稿,分布式一致性问题的选题呼声最高,分布式系统的内容是非常庞杂的,所以我们从其中几个重点的部分切入,慢慢展开。
今天重点来一起学习分布式系统一致性问题,不过内容比较多需要分几次写完。
1.为什么要学分布式
作为后端从业人员,我们在找工作写简历的时候除了高并发经验,一般还会写上自己熟悉|了解|掌握|精通分布式系统,所以高并发和分布式大多是成对出现的。
在拉勾上搜了个后端岗位:
分布式系统是个多金的知识点,那还不抓紧行动!
2. 熵增的分布式系统
关于什么是分布式系统,有很多文章介绍,其实这个并不难理解,大白话讲就是:工厂活多了一个人撑不住,那就多找些工人一起干,要让这么多人为了一个目标干得快干得好,就需要一些规矩和套路,否则就乱了。
从实践来看分布式系统属于重要的架构模式,对于互联网工程架构的演进,简单提一下为什么会出现分布式系统以及什么是分布式系统:
业务量的迅速增大,普通的单机系统无法满足要求,要么垂直扩展升级机器硬件,要么水平扩展堆廉价服务器,这也是主流可以想到的解决方法,目前来看互联网领域选择了后者-水平扩展。
水平扩展机器多机房部署升级服务集群规模来应对业务的增长,也就出现了分布式系统,这些分布式系统中的物理节点可能是多机房多网络场景部署的,相互之间通过网络进行通信和协作。
分布式系统就是为了解决巨大业务量和数据量而生的,但是庞大数量的节点来一起正确有序的完成共同的目标是需要理论和实践来锤打的,这也是分布式系统的重点内容。
一般我们常接触的分布式系统包括两大类:分布式存储和分布式计算。
分布式系统那么多机器要一起协调去完成任务也不是一件容易的事情,所以我们通常认为分布式系统是个熵增过程。
熵是描述一个系统内在混乱程度的物理量,对于一个宏观熵看孤立的系统来说,在没有外力干预做功的前提下,系统内在混乱程度是会不断增加的,也就是熵是增加的。
为了让系统保持有序就必须对其进行外力干涉,对于分布式系统而言,我们必须使用相应的策略和算法使整个系统保持有序和正确,所以认为分布式系统是个熵增过程。
这个并不难理解,就像我们为了保持房屋整洁,定期必须打扫,要不然就乱成一锅粥了。
如果对于系统不加以控制和干预,系统将自主走向混乱和无序。
3.分布式一致性问题的理解
分布式一致性到底是什么一致?
分布式的一致性可以表现在很多方面,这些都是个性问题,然而无论这些个性问题有多少,任何行为和状态的展示必然是以数据为基础的,所以这些个性的一致性问题最终都会映射到一个共性问题--分布式数据的一致性。
分布式系统中拥有很多独立的节点,这些节点一般来说可以独立进行存储和计算任务,这两项是最主要的任务类型,本质上计算和存储的过程仍然是围绕数据展开的,所以最终还是数据一致性。
在中心化结构中,存在管理节点和任务节点的区别,也就是每个节点的权利和义务是不一样的,管理节点可能负责分配任务给下属节点和收集计算结果等,总体承担协调者的角色,任务节点主要是承接任务,这样容易出现管理节点的单点问题。
在去中心化的结构中,各个节点的权利和义务是相同的,尽管没有单独指定领导者,在实际的运行中仍然会选举出领导者和failover动态更新领导者的问题,完全的去中心化系统并不多,相比中心化系统来说,去中心系统更加扁平也更加稳定,像Redis官方集群就是去中心化的实现,任何一个节点的故障都不会带来特别大的问题,因为节点是平等的。
无论在中心化还是去中心化的分布式系统中,任何一个节点的计算和存储结果都会对其他节点产生影响,这些独立的节点通过基础和特定的网络协议进行协作,从而形成一个整体。
4. 严格意义的数据一致性
经过前面的一些铺垫,我们开始重点部分的学习-分布式系统数据一致性问题。
我们必须要有个共识:严格意义上的分布式数据一致性是不存在的。
为啥不存在呢?
在分布式系统中数据存储是多节点主从备份的,一般做成读写分离,当客户端将数据通过主库的代理写入之后,在极其短暂的瞬间,主节点的数据是无法复制到从节点的,这个瞬间其他客户端读取到的从库数据都是旧数据。
聪明的读者盆友们可以体会一下瞬间这个词,当然你可以认为这是相对论的范畴,从物理角度去看可能更能体会。
我们以redis主从节点之间的数据复制来看同步复制和异步复制场景下的数据一致性问题:
一般来说,为了保证服务的高可用,主从节点的数据复制是异步的,因为同步复制延时无法保证,当然有的场景也是同步复制的,这样整体延时是无法保证的,假如是一主多从就更无法保证了同步复制的延时了。
所以我们不讨论严苛意义上的数据一致性,而是研究在我们认为可以接受的时间长度下的数据一致性问题,也就是在自身环境约束下的数据一致性。
单机系统的一致性和事务都是比较容易达到的,在分布式系统中由于所有节点的交互都要通过网络来实现,网络必然存在不稳定并且庞大系统中的单节点稳定性也是需要考虑的。
前面这段话,读起来云里雾里,我想表达的意思是:不要过分把对单机系统中的数据一致性要求照搬到分布式系统中,因为两者的约束不一样,我们要合理分析从而让分布式系统的一致性尽量接近单机系统。
solo和团战毕竟是不一样的,典型的《倚天屠龙记》中张无忌要去少林寺救谢逊,但是遇上的少林三位神僧渡厄、渡难、渡劫已经坐禅几十年,三人合一登峰造极,实在太难了,这也是优秀分布式系统的顶峰吧...
5.CAP理论和PACELC理论
我们知道cap理论描述了一致性、可用性、分区容忍性的关系。
在分布式系统中,由于节点物理分布和网络稳定性等原因,分区容忍性P是必然存在的,因此分布式系统必然要建立在分布式网络存在分区P的前提下。
在P的基础上我们对于C和A进行选择,当然并不是说在任何时刻我们都必须C和A二选一,在网络正常的情况下C和A我们也是可以都有的,并且每个系统设计目标也不一样,需要更加实际要求来进行选择。
分布式系统中P是必然存在的,我们在设计系统之初就要对C和A做平衡和选择,在正常的情况下跑出正确的结果是基本要求,在异常情况下仍然可以正常运行是设计重点。
在分布式系统中,我们使用PACELC理论比CAP理论更加合适,因为PACELC理论是CAP理论的扩展,简单来说PACELC理论的表述是这样的:
如果分区partition (P)存在,分布式系统就必须在availability (A) 和consistency (C)之间取得平衡作出选择,否则else (E) 当系统运行在无分区P情况下,系统需要在 latency (L) 和 consistency (C)之间取得平衡。
PACELC理论比CAP理论更适合分布式系统,它完全展现了出现网络分区和正常情况下的取舍平衡问题,特别地引入了L时延因素,来对一致性C进行说明,也就是我们常说的强一致性和弱一致性。
强一致性不必多说,对主从数据的一致性要求很高,一般会牺牲可用性来保证,弱一致性又可以分为最终一致性/会话一致性/单调读一致性/单调写一致性等情况,从实用的角度来说我们重点关注弱一致性的最终一致性情况即可。
6.分布式和BASE理论
我们知道由于网络稳定性原因,分布式系统出现网络分区是必须要考虑的问题,在一般的互联网场景中我们选择最终一致性来保证服务的高可用,也就是允许一段时间L的数据不一致,经过数据复制和同步后最终达到一致。
我们看下BASE理论,这是我们理解分布式系统一致性的重要理论基础:
BASE是基本可用(Basically Available)、软状态(Soft state)和最终一致性(Eventually consistent)三个短语的缩写。
BA基本可用是指:系统在绝大部分时间应处于可用状态,允许出现故障损失部分可用性,但保证核心可用。
S软状态是指:数据状态不要求在任何时刻都保持一致,允许存在中间状态,而该状态不影响系统可用性。
E最终一致性是指:软状态前提下,经过一定时间后,这些数据最终能达到一致性状态。
7.CAP&BASE&ACID的关系
CAP理论说明了分布式系统中一致性C 、可用性A、分区容错性P之间的制约关系。