集中式到分布式发展

集中式到分布式的演变

前言:

随着计算机系统规模变得越来越大,将所有业务单元集中部署在一个或者若干个大型机上的体系结构物,已经越来越不能满足当今计算机系统,尤其是大型互联网系统的快速发展,各种灵活多变的系统架构模型层出不穷。同时,随着微型计算机的出现,越来越多廉价的PC机成为了各大IT企业架构的首选,分布式的处理方式越来越受到业界的青睐。
计算机系统正在经历一场前所未有的从集中式到分布式架构的变革!

什么是集中式?

由一台或多台主计算机组成中心节点,数据集中存储于这个中心节点中,并且整个系统的所有业务单元都集中部署在这个中心节点上,系统所有的功能均由其集中处理
最大的特点就是部署结构简单,由于集中式系统往往基于底层性能卓越的大型主机,因此无需考虑如何对服务进行多个节点的部署,也就不用考虑多个节点之间的分布式协作问题

单应用架构:把所用软件和应用都部署在一个单机上

适合网站流量小,将所有的功能都部署到一台机器上,以减少部署的节点和成本
在这里插入图片描述

应用服务器和数据库服务器分离

因为在随着系统的访问量增加,一台服务器的Web服务压力会越来越大,这时需要考虑在增加一台服务器。
考虑把数据和应用服务各自部署在独立的资源上
一定程度上的减轻了服务器的压力,一定程度上解决了并发能力和数据存储性能
把 web服务器和数据库服务器分离,提高了单机的负载能力,也提高了容灾能力
在这里插入图片描述
一段时间后,系统高并发高访问持续不就,系统就变慢了,数据库的压力没问题,Apache服务也没问题,但是发现请求数多了,处理不过来,一台服务器的性能已经不能满足我们的需要了。
增加多台服务器对各个模块进行集群,负载均衡
服务器集群使整个系统解决高并发和海量数据的访问问题,使得单台服务器的性能上不再是问题。

应用服务器集群

在这里插入图片描述

问题来了:

集群的出现,同时也带来了一些问题,比如:

1.用户由谁来转发到具体的服务器。
2.用户访问到不同的服务器时如何维护session
这个时候就需要中间件,负载均衡来解决这些问题
Weblogic ,LVS,Haproxy,Nginx,F5……
在这里插入图片描述
在这里插入图片描述

虽然解决了系统的高并发问题,但是数据库的读写瓶颈又来了,高并发对需要同时写入和读取大量的数据,都需要连接数据库和更新数据库,连接资源争夺的很厉害

数据库的压力越来越大

解决方法:
数据库的读写分离
使用搜索引擎缓解读库的压力
引入缓存机制,缓解数据库的压力
数据库的水平垂直拆分

数据库的读写分离

为了减少数据库的压力,提高系统的效率,使数据库读写分离。
新的架构的出现,同时也会带来问题:主从数据库之间的同步,可以使用mysql自带的master-slave方式实现主从复制;对应数据源的选择,采用第三方数据库中间件,如mycat…
在这里插入图片描述

使用搜索引擎,缓解读库的压力

这样能提高查询速度,但也带来问题,如维护索引的构建。
在这里插入图片描述

引入缓存机制,缓解数据库的压力

把经常使用到的数据存储在一块内存中,减少数据库的访问量
使用缓存功能,系统访问遵循二八定律,把80%的访问量集中在20%的数据中,缓存分为远程分布式缓存和本地缓存,本地缓存速度较快,但是会与PC本身争内存。
对于热点数据,可以使用redis等来作为我们应用层的缓存;使用nosql的方式限制某些ip的访问频率如mongodb在这里插入图片描述

数据库的水平垂直拆分

垂直拆分:把数据库不同业务数据拆分到不同的数据库。
水平拆分:把同一个表中的数据拆分到两个甚至更多的数据库中。
在这里插入图片描述

什么是分布式?

一个系统,拆成n个子工程,每一个子工程配置服务器,独立运作。但是需要相互协作才能运转整个系统流程。每一个节点都可以配置集群。

对业务进行拆分改造 ,把不同的业务部署到独立的服务器。
通常使用分而治之的手段将整个系统业务分成不同的产品线,应用之间通过超链接建立关系,也可以通过消息队列进行数据分发,当然更多的还是通过访问同一个数据存储系统来构成一个关联的完整系统。
纵向拆分:大应用分为多个小应用,如果新应用比较独立,那么拆分为一个独立的Web应用。较为简单,梳理业务,可以剥离不相关的业务。 横向拆分: 把复用的业务拆分出来,新增的业务只需要调用分布式服务即可。复用的业务拆分比较难。需要知道各个业务的接口规范,依赖关系等。

应用的拆分

按照领域模型拆分为多个子系统。

在这里插入图片描述

各子系统间可能会相互调用

如用户数据需要在商品和交易中都需要查询。此时可能通过走服务化的方式进行解决。
在这里插入图片描述

分布式存在的问题

通信异常
由于网络的不可靠性,分布式环境下各节点之间每次进行网络通信,都会伴随着网络不可用的风险。就算顺利得完成了一次网路通信,其延时也会远大于单机操作
网络分区
当网络发生异常情况,导致分布式系统中部分节点之间的网络延时越来越大,最终导致组成分布式系统的所有节点,只有部分节点之间能够进行正常通信,而另一些节点则不能。我们把这种情况称为网络分区,俗称“脑裂”
节点故障
由于分布式环境下,有许多节点,每个节点都有可能出现故障。一些节点出现故障可能使系统变得不可用。
分布式事务
上面列举的几个问题,会引发其它一系列问题。其中一个非常重要的问题就是“数据一致性问题”。

服务之间的通讯技术RPC

在这里插入图片描述

分布式事物

在集中式环境下,也存在数据一致性问题,比如数据库的事务。
数据库事务的特性: ACID,A:原子性(Atomicity);C:一致性(Consistency);I:隔离性(Isolation);D:持久性(Durability)

倘若在分布式事务中,也严格按照ACID原则来实现的话,很可能出现系统可用性和严格一致性之间出现冲突。但是可用性和一致性都是至关重要的,缺一不可。为了兼顾这两种属性,出现了诸如CAP与BASE等分布式经典理论。

CAP

C(Consistency)指的依旧是一致性,指数据在多个副本之间是否能保持一致的特性。如果针对一个数据项的更新操作执行成功之后,所有用户都可以读取到其最新的值,那么这样的系统就被称为强一致性(严格一致性)。
A(Availability)指的是可用性,指系统提供的服务必须一直处于可用状态,对于用户的每一个操作请求总是能够在有限时间内返回结果。
P(Partition tolerance)分区容错性,分布式系统在遇到任何网络分区故障时,仍需要能够保证对外提供满足一致性和可用性的服务
CAP理论的核心就是权衡利弊,它告诉我们,任何分布式系统都无法同时满足这三点,需要权衡利弊,而不是追求完美

BASE

BA(Basically Available)指基本可用,S(Soft State)指软状态,E(Eventually Consistent)最终一致性。
BA指的是系统出现不可预知的故障时,允许损失“部分”可用性,但这绝不等于不可用。比如响应时间上的损失或者请求高峰期部分用户被引导到降级页面。
S指的是系统允许不同副本之间的同步存在延时,但不会影响系统的整体可用性。
E指系统经过一段时间的同步,最终能够到达一个一致性状态,而不用保证数据的实时一致性(强一致性)。

常见的分布式事务解决方案

基于XA协议的两阶段提交
XA中大致分为两部分:事务管理器和本地资源管理器。其中本地资源管理器往往由数据库实现,比如Oracle、DB2这些商业数据库都实现了XA接口,而事务管理器作为全局的调度者,负责各个本地资源的提交和回滚。XA实现分布式事务的原理如下:
总的来说,XA协议比较简单,而且一旦商业数据库实现了XA协议,使用分布式事务的成本也比较低。但是,XA也有致命的缺点,那就是性能不理想,特别是在交易下单链路,往往并发量很高,XA无法满足高并发场景。XA目前在商业数据库支持的比较理想,在mysql数据库中支持的不太理想,mysql的XA实现,没有记录prepare阶段日志,主备切换回导致主库与备库数据不一致。许多nosql也没有支持XA,这让XA的应用场景变得非常狭隘。

在这里插入图片描述

第一阶段
应用程序调用了事务管理器的提交方法,此后第一阶段分为两个步骤:
事务管理器通知参与该事务的各个资源管理器,通知他们开始准备事务。
资源管理器接收到消息后开始准备阶段,写好事务日志并执行事务,但不提交,然后将是否就绪的消息返回给事务管理器(此时已经将事务的大部分事情做完,以后的内容耗时极小)。
第二阶段
事务管理器在接受各个消息后,开始分析,如果有任意其一失败,则发送回滚命令,否则发送提交命令。
各个资源管理器接收到命令后,执行(耗时很少),并将提交消息返回给事务管理器。

事务管理器接受消息后,事务结束,应用程序继续执行。 为什么要分两步执行?一是因为分两步,就有了事务管理器统一管理的机会;二尽可能晚地提交事务,让事务在提交前尽可能地完成所有能完成的工作,这样,最后的提交阶段将是耗时极短,耗时极短意味着操作失败的可能性也就降低。 同时,二阶段提交协议为了保证事务的一致性,不管是事务管理器还是各个资源管理器,每执行一步操作,都会记录日志,为出现故障后的恢复准备依据。 二阶段提交协议的存在的弊端是阻塞,因为事务管理器要收集各个资源管理器的响应消息,如果其中一个或多个一直不返回消息,则事务管理器一直等待,应用程序也被阻塞,甚至可能永久阻塞。

消息事务+最终一致性

所谓的消息事务就是基于消息中间件的两阶段提交,本质上是对消息中间件的一种特殊利用,它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操作成功并且对外发消息成功,要么两者都失败,开源的RocketMQ就支持这一特性,具体原理如下:在这里插入图片描述
1、A系统向消息中间件发送一条预备消息2、消息中间件保存预备消息并返回成功3、A执行本地事务4、A发送提交消息给消息中间件
通过以上4步完成了一个消息事务。对于以上的4个步骤,每个步骤都可能产生错误,下面一一分析:
步骤一出错,则整个事务失败,不会执行A的本地操作
步骤二出错,则整个事务失败,不会执行A的本地操作
步骤三出错,这时候需要回滚预备消息,怎么回滚?答案是A系统实现一个消息中间件的回调接口,消息中间件会去不断执行回调接口,检查A事务执行是否执行成功,如果失败则回滚预备消息
步骤四出错,这时候A的本地事务是成功的,那么消息中间件要回滚A吗?答案是不需要,其实通过回调接口,消息中间件能够检查到A执行成功了,这时候其实不需要A发提交消息了,消息中间件可以自己对消息进行提交,从而完成整个消息事务

基于消息中间件的两阶段提交往往用在高并发场景下,将一个分布式事务拆成一个消息事务(A系统的本地操作+发消息)+B系统的本地操作,其中B系统的操作由消息驱动,只要消息事务成功,那么A操作一定成功,消息也一定发出来了,这时候B会收到消息去执行本地操作,如果本地操作失败,消息会重投,直到B操作成功,这样就变相地实现了A与B的分布式事务。原理如下:
在这里插入图片描述
虽然上面的方案能够完成A和B的操作,但是A和B并不是严格一致的,而是最终一致的,我们在这里牺牲了一致性,换来了性能的大幅度提升。当然,这种玩法也是有风险的,如果B一直执行不成功,那么一致性会被破坏,具体要不要玩,还是得看业务能够承担多少风险。

TCC编程模式

所谓的TCC编程模式,也是两阶段提交的一个变种。TCC提供了一个编程框架,将整个业务逻辑分为三块:Try、Confirm和Cancel三个操作。以在线下单为例,Try阶段会去扣库存,Confirm阶段则是去更新订单状态,如果更新订单失败,则进入Cancel阶段,会去恢复库存。总之,TCC就是通过代码人为实现了两阶段提交,不同的业务场景所写的代码都不一样,复杂度也不一样,因此,这种模式并不能很好地被复用。

## 分布式总结
分布式事务,本质上是对多个数据库的事务进行统一控制,按照控制力度可以分为:不控制、部分控制和完全控制。不控制就是不引入分布式事务,部分控制就是各种变种的两阶段提交,包括上面提到的消息事务+最终一致性、TCC模式,而完全控制就是完全实现两阶段提交。部分控制的好处是并发量和性能很好,缺点是数据一致性减弱了,完全控制则是牺牲了性能,保障了一致性,具体用哪种方式,最终还是取决于业务场景。作为技术人员,一定不能忘了技术是为业务服务的,不要为了技术而技术,针对不同业务进行技术选型也是一种很重要的能力

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值