单元化架构解决了什么问题

文章摘自:单元化架构解决了什么问题 - 兰希姑娘的文章 - 知乎 https://zhuanlan.zhihu.com/p/339600956

作者:兰希姑娘
链接:https://zhuanlan.zhihu.com/p/339600956
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

首先,我们先来看下单元化是什么。

所谓单元,是指一个能完成所有业务操作的自包含集合,在这个集合中包含了所有业务所需的所有服务,以及分配给这个单元的数据。

假如一个业务有30亿数据,采用单元化架构部署的话,我们可以把数据拆解为3份,每份10亿数据,建立3个单元,这三个单元,业务服务一模一样,但是数据库存储的数据不同,分别是10亿数据。

这里根据数据进行单元的拆分,数据需要具备可拆分的属性,比如用户ID等全局唯一标识信息,否则无法拆分单元。

上面拆解的单元其实是逻辑单元的概念,实际部署的时候,每个单元需要遵从常用的部署方案。

比如,常见的部署方案是两地三中心、同城双活、异地多活等容灾方案。

以两地三中心为例,机房建在两个城市、共三个机房,其中一个城市两个机房。

同城的两个机房同时提供服务,细说的话,其实是业务服务双活,数据库仍然是一主一备,主提供读写服务,备提供读服务,主从之间采用强同步,备份机房的业务服务写操作访问的仍然是主服务所在机房的数据库。

当一个机房的业务服务故障的时候,未发生故障的机房承接所有流量,进行主从的切换。

同时在另外一个城市,搭建一个机房,提供一套服务和数据库,但是服务不对外提供服务,数据库也处于冷备状态,同城备份机房异步方式对其进行数据同步。

当双机房所在城市故障时,未发生故障的城市的机房承接所有流量。

还有一点需要说明的是,上面的故障都是机房维度和城市维度的故障考虑。

实际上,每个机房的数据库本身也会分主从数据库,采用异步方式同步。

这里你可能会有疑问,为什么每个机房的备库是异步复制呢?尤其主数据库所在机房与另外机房的数据库是强同步,而与本机房的从库是异步复制。

这里有几个概念需要明确下:

1.强同步的效果:一主多从模式下,即使主设置了与多个从库都是强同步模式,最终的效果其实是只要有一个从库收到了数据,主库就认为强同步结束(请注意:这里描述的是一种常见的实现方式,当然也有其他实现方式),而又因为本机房从库距离本机房主库较近,如果设置了本机房从强同步,大部分时候实现的是本机房从库的强同步,跨机房的库没有实现强同步。

2.跨机房容灾能力更强主从模式、多机房建立服务目的是为了容灾,因此,如果在跨机房从、本机房从之前选择一个建立强同步的话,很明显,实现跨机房强同步有更好的容灾能力,因为如果本机房挂了或者本机房主挂了,都可以使用跨机房的强同步数据库, 而本机房挂了的情况下,主机房从库起不到容灾作用。

基于1和2,为了达到更好的容灾效果,一般会选择跨机房数据库为强同步。

你可能又会问,本机房的从存在意义又是什么呢?

当然还是容灾考虑,比如,当跨机房挂掉的情况下, 这时候就只有本机房从可以作为容灾数据库了,如果原跨机房数据库提供读能力,那么读的流量会达到本机房从上,并且本机房主与本机房从数据同步方式会由异步改为强同步。

一个逻辑单元实际部署的时候,会按照两地三中心等类似容灾方案部署,如下图。

 

这里提醒下,本文提到的很多概念,比如多活、数据库主从、上面的部署图等,实际实现方式可能会有很多情况,这里也只是列出其中一种方案,以方便说明单元化的知识,所以如果有相关的疑问,可以不用太纠结。

接下来,我们聊一聊为什么要进行单元化的设计?

单元化设计首先是为了方便扩容。

业务使用量总是在不断增长,为了满足业务需求,业务服务系统、数据库都需要不断的扩容,以支持越来越多的业务数据。

正常情况下,为了提升业务服务能力,业务服务一般都是分布式部署,同时对外提供服务,而数据库由于数据量很大,也会进行分片存储,每个业务服务可能访问所有的数据库。

这种情况存在的问题是,每个业务服务都需要与每个数据库建立连接,当业务服务数量随着业务量逐渐增多的时候,需要建立的连接数越来越多,而每个数据库可以承接的连接数是有限的,当超过数据库连接数上限的时候,再增加业务服务也无法实现扩容。

这里,我解释下,为什么数据库已经进行了拆分,每个数据库只会接收该分片数据的请求,为什么还会出现随着业务服务的扩容,连接数越来越多的问题。

通常架构设计的时候,建立一个数据库连接可以持续处理很多请求,所以假如请求来自一个业务服务,那么可以简单认为只需要建立一个连接即可(实际上会更多)。

当这个请求可能来自于任何一个服务,因此,就需要数据库建立与所有服务的连接。

上面我们提到,随着业务服务的扩容,越来越多的服务建立与数据库的连接,这就会导致数据库连接数增加。

解决这个问题的关键就是:如何实现随着业务服务的扩容,保持数据库连接数不变。

如果,我们在业务服务层面就可以对流量进行切分,切分方式同数据库,那么,某分片数据库只需要与该业务服务建立连接即可,同时,当业务量增加的时候,只需要,同步新增相同的业务服务和对应的分片数据库,新的业务访问走新增的服务即可,这就可以解决上面的问题。

这里,只接收特定请求的业务服务+分片数据库组成一个单元,这个单元内就可以完成该范围用户的一切操作,系统扩容按照单元粒度逐渐扩容。

这就是为什么需要单元化的一个原因。

要达到单元化的目标,业务需要具备的条件是:业务数据是可以水平切分的;业务相关所有服务都可以按照同一个规则切分,比如都按照用户ID切分,只有这样,才能实现不同的业务服务访问同一个分区数据库的小闭环。

再来聊聊容灾。

首先,容灾能力主要靠两地三中心,数据库主从等方式来实现的。

其次,由于某个单元服务或者数据库出现问题,只会影响该单元的请求,可以实现单元粒度的故障隔离,因此从容灾角度看,单元化也是非常好的。

并非所有的服务都可以单元化,实际上,一个业务即使实现了单元化,最终的效果也一定是部分服务的单元化,不能单元化的服务仍然按照传统方式设计。

技术精进是一场修行,相信自己和时间力量。

 
posted @ 2023-07-25 23:38  你的雷哥  阅读(181)  评论(0编辑  收藏  举报