聊聊分布式

1、关于分布式

分布式系统架构的第一原则:不要分布。这句话揭露了分布式系统的很多特征。
那么为什么还要分布式呢?为了性能。随之而来的问题是故障的概率增大。
所以,分布式系统的两个关键目标,性能与容错。分布式的所有基本上都是围绕这两个方面展开的。

2、关于分布式设计的两大思路

中心化与去中心化。

2.1、中心化

即将node分为manager与worker,即管理节点与工作节点。
中心化的设计最大的问题就是一旦manager挂了就全完了,但是又很难做多个manager,为此多数中心化系统都采用了主备方案,即当主manager挂了后,备顶上(热备、冷备,手动切换、自动切换);
中心化的另1个问题,当manager成为性能瓶颈时,该怎么办?这是在系统设计和实现时应该考虑的。

2.2、去中心化

所有的node都平等,这里的平等实际上是对外平等。其实,真正去中心化的分布式系统很少很少,大多都是外部看起来去中心化了,但工作机制采用了中心化的设计思想。
对比中心化,去中心化的leader是选举出来的,当leader产生故障后,自动选举新的leader。我们比较熟悉的去中心化架构,比如zookeeper和etcd,顺便提一下zookeeper采用的ZAB算法(Paxos算法的近亲兄弟),etcd采用的Raft算法。据说Paxos算法太复杂了,才导致了Raft这种算法的出现,有对算法感兴趣的,可以了解了解,反正我对算法是一脸懵逼。
去中心化最大的问题是“脑裂”。这种情况发生的概率很低,但是影响很大。通常是由于集群间网络的问题导致的。一般产生脑裂后,处理方式都是规模较小的集群“自杀”或者拒绝提供服务。这也是为什么去中心化的服务在部署时尽量是奇数个节点,如果是偶数个节点,那么会存在脑裂后两个集群规模相同,那此时谁该自杀呢?

3、关于分布式中的CAP

C:一致性Consistency:所有节点上的数据时刻保持同步。
A:高可用性Availability:每个请求都能接收1个响应,无论响应成功或失败。
P:分区容错性Partition tolerance:系统应该能持续提供服务,即使系统内部(某个节点分区)有消息丢失。

3.1、CAP理论

被戏称“帽子理论”,是”帽子理论“,不是”帽子戏法“:三者在分布式系统中无法同时实现,最多只能实现其二。其实CAP理论在2003年提出后,各种质疑不断,时隔12年后,CAP理论的作者hold不住了,出面进行了一些澄清,同时对CAP理论做了一些限定。当初的一些质疑,个人觉得是主要针对分区容错性,目前来看,我们多数情况下都是在一致性和可用性之间做取舍,比如做注册中心的zookeeper满足CP,而eureka满足AP。特别说明:CAP理论,原作者在2012年重写论文,声明不支持数据库事务之类的场景。

3.2、zookeeper

具有一致性,那么它为撒不满足高可用性呢?举个例子,当出现了一些故障,比如leader挂掉,半数节点没有心跳等,需要重新选主,在选主的这段时间内,是无法提供服务的,而通常,选主过程是很耗时的。

3.3、eureka

由于它的自我保护机制,当一些服务出现异常后,仍然能够提供服务。对于zookeeper和eureka的一些设计思想及理念,可以好好看看,这里就不详述了。
ps:提1个问题,如果eureka服务挂了,serviceA掉serviceB还能调通吗?

4、关于分布式事务
4.1、事务

先说说事务,通常我们所说的事务都是指数据库事务。
说到事务,就要说到事务的4个特性ACID。
A:原子性Atomic:事务必须是原子工作单元,对其进行数据修改,要么全都执行,要么全都不执行;
C:一致性Consistent:事务在完成时,必须使所有的数据都保持一致状态,事务结束时,所有的内部数据结构(如B树索引或双向链表)都必须是正确的;
I:隔离性Isolated:由并发事务所做的修改必须与任何其他并发事务所做的修改隔离;
D:持久性Durable:事务完成对系统的影响永久性的。
一般来说,隔离性通过锁实现,原子性、一致性和持久性通过日志文件来实现。
对于单机事务是很好控制的,那么对于分布式事务又是怎么处理的呢?

4.2、分布式事务的解决方案

其实最好的办法是避免分布式事务,洞鉴中有很多地方采用的是这种方法,比如你会看到,创建底库、添加人像之类的操作,调core侧接口成功后,如果在业务侧出现了一些异常,又会在catch里面调删除的接口。然而这种方法,代码会显得及其的臃肿。

4.2.1、基于XA协议和X/Open DTP模型的两阶段提交

XA协议由Tuxedo(被Oracle收购了,突然感觉Oracle干的最多的事就是收购)提出,后交给X/OPEN组织,XA协议定义了很多接口,一般的数据库都实现了它定义的接口。
基于X/Open DTP模型(这个模型很经典),提出了二阶段提交(2PC)方案,。JAVA中的JTA是其一种实现。
在这里插入图片描述
AP:用户程序,大部分是CRUD代码(我们的拿手操作)。
RM:数据库或很少被使用的消息中间件。
TM:事务管理器、事务协调者。负责解释AP发起的XA指令,并且调度和协调参与事务的所有RM,确保事务正确完成(或者回滚)。
可以看出,AP负责触发分布式事务,RM负责执行XA指令(每个RM都只执行自己的),TM负责协调、检查每个RM的执行情况。
了解了X/Open DTP中的角色了,我们来说说二阶段,
在这里插入图片描述
1,prepare阶段,发起投票表决,RM通知TM能否成功提交
2,commit阶段,当且仅当所有的RM同意提交时,TM通知所有的RM提交,否则回滚。
二阶段提交设计的精妙之处在于:由于commit阶段相对prepare阶段耗时很少,而采用这种方式,分布式事务失败的概率则可以认为是(commit阶段耗时)/(commit阶段耗时+prepare阶段耗时),因此它的概率是非常小的。
虽然说二阶段提交设计的很精妙,然而它存在一个致命的问题,就是效率(性能)很低,本来分布式是为了提高性能的,在这里,一夜回到解放前,所以对于追求性能、响应速度等的场景基本上都不会采用该方案。

4.2.2、TCC方案

在这里插入图片描述
看到这个图知道为撒叫TCC了吧。
在仔细看这个图,是不是和X/Open DTP的图里面的几个角色比较神似,其实,这种方案也是基于X/Open DTP模型提出来的,那么它相对于2PC有什么优势呢?笔者认为,这种方案不需要事前确认每个RM都能正常的提交,而是直接先confirm,当出现异常后再在进行cancel。因为通常情况下,异常情况比较少,所以需要cancle的就比较少,对比2PC少了一步等待确认的过程,从而使得效率(性能)要优于2PC。这种思想可以类比乐观锁、CAS。
这种方案虽然说提高了性能,但是也有不足之处:
a、对代码的入侵极大。
b、实现时需特别注意,对于一些操作需要幂等。

4.2.3、基于可靠消息的最终一致性方案

这里先说说BASE准则:
虽说XA事务保证了数据库在分布式系统下的ACID特性,但是也带来了一些代价,特别是性能,因此对于并发、响应时间要求比较高的场景肯定不适用,于是,eBay公司选择了放宽数据库的ACID要求,提出了一套新准则,即BASE准则,Basically Available,Soft-state,Eventually Consistent,即系统主要可用、软状态、(数据)最终一致性。
在BASE准则的基础上,有了基于可靠消息的最终一致性方案。
在这里插入图片描述
该方案实质是把分布式事务转换成两个本地事务,上游事务(含发送消息到消息队列),下游事务利用重试机制,保证数据最终一致。
这种方案过程非常的清晰,因此目前很多分布式事务都选择此种方案,但是它里面有些细节地方需要注意,比如重试时,操作是否幂等。

4.2.4、GTS全局事务服务-Global Transaction Service

GTS是阿里中间件部门研发,为分布式事务提供一站式解决方案。
据说优势很多,比如性能强、入侵低、容错强等,GTS包括客户端client、事务协调器server、资源管理器RM。Client主要用来界定事务边界,完成事务的发起与结束。GTS RM完成事务分支的创建、提交、回滚等操作。GTS Server主要负责分布式事务的整体推进,事务生命周期的管理。看到这里是不是想起了X/Open DTP模型?
这种方案据说很牛13,但是我不是很了解,这里只是简单的提一下,有兴趣的可自行研究。可以参考参考https://www.cnblogs.com/jiangyu666/p/8522547.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值