当前位置: 首页 > 科技观察

浅谈互联网分布式架构演进

时间:2023-03-18 11:05:34 科技观察

互联网系统往往面临庞大的用户群体,这意味着系统需要时刻面临大量高并发请求、海量数据存储等挑战。在解决这些问题的同时,必须保证系统的高可用性。同时,互联网行业更新迭代迅速。在发展初期,很多互联网巨头为了快速发布产品上线占据用户流量,都会以最简单的应用架构形式部署系统,而不会过多考虑未来的应用架构。因此,很多互联网公司发展到一定规模后,都会进行相应的结构改造和改进,以适应业务发展。这几年经历过很多公司,从一个开发人员寥寥无几的小公司,发展到10亿+用户规模的公司,所以对互联网公司的系统应用架构演进有一些深刻的体会。单点应用公司发展初期,由于用户量小,系统并发请求不高,数据量小,往往只需要将应用部署在一个单点满足业务需求:以上是典型的早期互联网应用架构模式,应用只需要部署在单台服务器上,甚至数据库也放在同一台服务器上,流量直上直下,一口气完成。由于应用和数据库都是一体的形式,缺点很明显,无法进行故障转移。一旦某个应用或数据库出现故障,整个系统将不可用。应用SOA1.水平拆分单一应用缺乏故障转移。同时,随着请求数量的增加,无法处理单个应用部署的请求。常见问题是应用连接数满,用户请求超时。而且需要很长时间才能回复。如上图所示,系统被横向拆分,部署了多个应用实例。同时,网关对流量进行平均分配,有效降低单个应用的请求压力。同时,应用服务有故障转移。当服务遇到故障时,只要仍然保持着多个应用实例,系统就可以正常运行(还需要考虑降级过程)。这是应用SOA的初级阶段。2、纵向拆分随着公司业务的快速发展,业务量越来越大。一个应用承载所有的业务,所有的业务代码都放在同一个代码仓库中。虽然部署方便,运维成本低,但是缺点非常明显。随着业务量越来越大,项目的代码量急剧增加,各个业务的复杂度也越来越复杂,耦合度越来越高。而且随着代码量的增加扩展性越来越差,发布周期窗口会越来越长,无法快速迭代快速上线。为了解决以上问题,我们可以按照业务维度对系统进行垂直拆分。例如,商城系统可以拆分为用户服务、交易服务、订单服务等,如上图所示。至此,系统已经横向纵向拆分,应用层基本完成了SOA。存储拆分1.存储读写分离随着业务的发展,发现应用服务不再是负担,数据层反而成为了整个系统的唯一单点。此时,随着系统TPS的增加,应用实例部署越来越多,单个数据库的连接数增加,数据写入效率变慢。单一的主库无法维护整个系统的数据读写。此时数据层读写分离,数据库拆分为一个主库和若干个从库。主库仍然负责写入数据,从库负责读取数据,可以大大减少数据写入。入境的负担。但是,读写分离意味着读写并不是严格同步的。主库与从库同步数据需要一定的时间,但大部分数据延迟是可以接受的。2、存储垂直拆分后,数据读写分开,一定程度上减轻了数据写入的负担。但是我们发现整个系统只有一个主库,各个业务领域的数据写入都严重依赖这个主库。一旦上来,单主数据库根本搞不定。与应用的垂直拆分类似,存储层的垂直拆分也是按照业务维度进行拆分,拆分成若干个库,比如商城系统可以拆分成用户库、订单库等.从上图可以看出,对于数据写入流量,每个业务域都单独承担了自己的数据读写。至此,一个基本完整的分布式应用架构基本成型,接下来需要解决与数据库拆分相关的分布式事务问题。3、存储层次拆分当业务发展到一定程度时,单一的数据库和单一的表已经不足以承担各自业务领域的数据读写。这个时候怎么办?这时候我们可以按照用户维度对数据进行横向拆分比如根据用户id的后两位,将一个大表拆分成100个小表,然后创建100个数据库(当然,数据库的数量可以少于表的数量)。表架构。分库分表可以有效减少单表数据的数据量,还可以根据用户维度将流量分配到各个数据库和表中,性能得到全面提升。至此,一个完整的分布式架构已经形成。其实这就是目前很多大型互联网公司的部署架构现状。随着业务的进一步发展,单元化部署类似于一些10亿+用户的巨头公司,所以他们的应用实例部署规模非常大,会伴随着数据库连接数不足的问题。从上图我们可以看出,随着应用实例的增加,数据库链接数也会增加。为什么?因为每个数据库实例都是应用实例共享的,那么你可能会问为什么要共享。因为网关的流量分布很均匀,你的每一个请求都可能被丢弃。对于任何一个应用实例,那么应用实例必须根据你的用户ID将数据丢到指定的表中。此时,应用程序实例必须连接到所有数据库才能这样做。对于一个10亿+用户的系统来说,本身流量就已经很高了。横向扩展服务极其困难。甚至已经达到数据库连接数上限,服务无法继续横向扩展。那我们该怎么办呢?既然数据可以按照用户维度分库分表,为什么请求的流量不能按照用户维度进行横向拆分呢?我们将应用实例按照用户维度进行隔离,每个单元部署系统的所有服务,用户可以在某个单元完成所有的业务流程,如下图所示:可以看出,经过单元化隔离后,数据库连接数呈指数级减少。如果单元化粒度拆分的越小,数据库的连接数就会越少。数据分区对于大型互联网公司,往往有多个物理机房。在多个机房中,部署方式主要分为两种:垂直部署(扩展方式):将系统服务和数据库分成若干部分,每个机房都有一些服务和数据库,可以解决机房的容量问题,但是要完成一项业务,可能需要经过多个机房的协作,如果一个机房发生故障,整个系统将不可用,不具备容灾能力;水平部署(镜像模式):每个机房都有所有业务,即每个机房可以完成一次业务转移,并具备容灾能力。一般大部分公司都会采用第二种水平部署模式,但是这种模式下需要解决数据分区问题。我们知道应用是无状态的,我们可以很容易的把流量随机分配到各个机房,让每个机房承载一定的流量。但是数据不好。每个机房都有一个独立的数据库是非常困难的。那么如何解决数据分区的问题呢?我们已经谈到了单元化部署。由于一个单元包含了系统的所有服务,我们可以简称为逻辑数据中心(LogicalDataCenter,LDC)。同样,在水平部署模式下,一个物理机房也拥有所有的服务,我们可以简称为互联网数据中心(IDC)。所以,他们的关系:LDC是IDC的逻辑分工。说白了:LDC是基于IDC的逻辑划分。一个LDC逻辑数据中心被称为一个“单元”。每个单元都有所有已部署的应用程序。每个单元可以分配到任意一个物理机房,每个物理机房可以有多个单元,如下图:如上图所示,物理机房水平部署模式下,如何单元化解决数据分区问题?前面我们说了按照用户维度做单元化隔离部署,那么我们也可以对数据进行分区,按照用户维度对数据进行分区。比如对用户后2位数据进行分区,一共拆分100份,每个单元负责几份。以数据为例,系统中有10个单元,每个单元负责10个分区的数据。这样每个单元都有一个独立的数据分区,可以完全隔离数据。单元化部署架构下如何扩容?应用扩展系统单元化隔离部署后,通常数据库连接不再是瓶颈,这也是单元化部署带来的好处之一。这时候,我们很容易通过为单元中的每个服务添加若干个应用实例来达到扩容的目的。单元扩容增加单元数量,增加后的每个单元都会重新分配流量。但是需要注意的是,增加单位数据并不意味着数据分区会增加。数据层与应用层的扩容无关,但值得注意的是,单元扩容可以有效减少数据库连接数。每个单元连接的数据分区是根据该单元负责的用户维度的流量来区分的,如下图:很容易增加一个单元进行存储扩展。但是在原有数据分区下扩容并不容易,因为涉及到表路由规则的变化,需要迁移数据,而且一般分库分表时,未来业务的容量会是预估了提前的需求,每个用户维度都已经提前预分片了,所以如果数据需要扩容,就需要对数据进行重新分片。这里涉及到数据迁移,就不赘述了。本文转载自微信公众号《后端进阶》,可通过以下二维码关注。转载本文请联系后端高级公众号。