技术分析:分布式系统的核心问题

在互联网的初始阶段,企业通常使用单一的架构来构建自己的应用系统。然而,随着企业的不断发展,访问系统的次数不断增加,数据量也急剧增加。数据存储是要解决的第一个问题。在这个大数据时代,数据是企业的生命线。数据库的单一结构难以满足数据的存储。此时,我们需要对数据进行分段。数据分割分为垂直分割和水平分割。

数据分段和数据库体系结构

在数据分割之前,我们所有的业务都放在一个数据库中,例如我们的用户业务、商品业务和订单业务。数据库的结构如下:

当业务发展到一定规模时,数据库很难满足数据的存储,这导致数据访问速度变慢和用户流失。此时,我们需要对数据进行分段,以便将其从单个数据库的存储分散到多个数据库的存储中。分割数据时,应遵循先垂直后水平的原则。

数据的垂直分割也是数据的垂直分割,它根据业务对数据进行分割。在上例中,我们将数据库分为:用户库、商品库和订单库。原始数据库分为三个数据库,分散了数据存储和数据读取的压力。如图所示:

但是,随着业务的发展,单个业务库也会遇到存储瓶颈,如:用户快速增长,导致单个用户库无法存储,用户访问速度变慢等。此时,我们将水平划分数据,并根据一定的规则将用户平均划分为多个数据库,即水平扩展原来的单用户数据库。如图所示:

在这里,我们只是水平分割两个数据库,我们可以根据自己的系统将它们分割成更多的数据库。

我的猫

我们已经规划了数据库的整体结构,那么当我们开发数据时,如何确定从哪个数据库读取数据呢?或者当插入一段数据时,数据将被插入哪个数据库?数据库的选择是留给开发人员的吗?还是有统一的代理层?当开发人员在开发时,重点是业务。复杂的业务已经占据了他们的大部分精力。如果要求他们考虑数据库问题,他们的压力将非常大。此外,每个开发人员的代码风格也不同,导致项目混乱、人员过多和维护困难。因此,我们经常使用代理层来统一处理数据碎片。此时,我们的MyCAT中间件登场了,它充当统一数据库层的代理。如图所示:

MyCAT以统一的方式充当数据库层的代理,向外界公开地址,应用系统直接与MyCAT连接,就像与普通的MySQL连接一样,没有任何区别。所有CRUD操作都直接对应于MyCAT,然后MyCAT进行特定的数据分段。数据分段的过程对开发人员来说是透明的,不需要额外的处理。这样,开发者只需要关注业务。

我的猫集群

可用性对于一个系统来说非常重要,尤其是在今天的互联网时代,当系统宕机一分钟,损失非常严重。因此,在构建系统时,我们经常使用集群方法,某个节点的不可用性并不影响整个系统的可用性。在前面的例子中,我们所有的节点都是单个节点,并且有一个单点故障,这是我们不想看到的,因此我们需要构建一个集群。我们可以成为所有6个商业数据库的主人。此时,用户1库可以被设置为用户1(主)和用户1(从),用户2库可以被设置为用户2(主)和用户2(从)。订单仓库和商品仓库可以进行同样的操作,如图所示:

这样,我们的业务数据库中就没有单点故障,但是我的猫变成了单点故障。如果MyCAT失败或者MyCAT携带大量数据库请求,MyCAT将成为整个系统的唯一瓶颈。所以我的猫,我们如何建立集群?一些小型合作伙伴可能已经说过,我们将部署另一个MyCAT,它与以前的MyCAT配置相同。是的,这只是第一步。我们有两个MyCAT连接数据库。我们的应用系统需要连接两个我的猫吗?我们如何为两只我的猫分配请求?这会增加应用系统的复杂性吗?因此,我们在两个MyCAT之上添加了一个负载平衡器,它可以根据某些规则将请求分发到两个MyCAT。这个负载平衡器使用HAProxy。总体结构如下:

就这样,我的猫(MyCAT)的单点故障得到了解决,但HAProxy又变成了单点故障。这很有趣吗?似乎总有一点是无法解决的。这里的最后一个单点故障可以通过使用“保留”进行故障转移来解决。两个保持虚拟(KeepAlived)可以提供一个虚拟IP,服务系统直接连接到这个虚拟IP。以下过程对应用程序系统是透明的。如图所示:

这是我们最后的数据库架构,没有单点故障。

分布式事务和分布式标识

在划分数据库和表之后,还会出现以下问题,即身份问题和分布式事务问题。分布式标识和分布式事务在我的猫中都有相应的解决方案,我们可以在我的猫中配置它们。

分布式限流

解决性能问题最有效的方法是根据系统的承载能力在源端限制访问请求的数量。在本节中,我们将重点讨论基于Nginx的网关层限流和基于Redis+Lua的分布式限流。

在Nginx网关层的限流方案中,我们将从两个不同的维度引入基于IP和服务器的限流方案,包括对访问频率和并发索引的限制。在Redis+Lua限流方案中,我们将引入Lua语言来编写一个限流脚本,然后将其植入Redis来控制请求的数量。

大家都在看

相关专题