机房容灾设计的架构演进起,你准备好了吗?

2024-05-08
来源:网络整理

我还依稀记得去年双11在支付宝作战室。 临近0点的时候,值班室里所有人都盯着二级监控市场。 当峰值交易曲线慢慢攀升,最后变得极其陡峭时,值班室的同学们都兴奋不已,欢呼声也随着曲线的攀升而达到顶峰,583,000笔交易/秒,这也是一个新的峰值交易记录。 但与往年相比,翻了一番,增长了30%到40%,增速还是小很多。

2010年双11的支付峰值为每分钟2万笔。 到2017年,这一数字已增至每秒25.6万笔支付,去年又增至每秒58.3万笔支付,是2009年首届双11的千余倍。

为了承受如此大的支付TPS,蚂蚁做了大量的顶层架构设计和底层实现优化,其中最核心的就是LDC架构。

LDC的全称是:Data,逻辑数据中心。 之所以称为LDC,是相对于传统IDC(Data)提出的概念。

IDC相信大家都知道它是一个物理数据中心。 说白了,就是一个可以搭建网站的物理机房。

LDC(逻辑数据中心),核心架构思想是,无论你的物理机房如何部署,比如你可能在两个不同的城市有3个IDC(常说的两地三中心),它们在逻辑上都是统一。 我认为它是逻辑上的一个整体,统一、协调。

LDC为何出现?

LDC解决了什么问题? 我们必须从建筑的演变开始。 我们通过一个具体的应用来推演上一篇文章中讨论的机房容灾设计的架构演进。

我们先看下图所示的单体应用架构。 请求到网关接口,网关接口直接调用应用或服务,服务调用存储层查询或写入数据,一次完成。

这种架构模型最大的风险是服务和存储是单点,访问能力和性能受到存储和应用的容量和性能的限制。 在灾难恢复方面,一旦发生故障,只能等待单点应用或存储的恢复。 。

后来工程师开始横向拆分应用,纵向拆分服务。

大家应该都熟悉水平拆分,这意味着添加服务器并在每台服务器上部署实例。 垂直拆分是指按领域拆分服务。 比如一个交易系统有商户域、产品域、用户域、订单域等,拆分成多个微服务,服务解耦,服务可以独立发布,应用复杂度会更高。

这种分布式架构解决了单点服务的问题。 如果某个服务器宕机了,服务仍然可用,但存储层仍然是单点。 随着业务的增长,添加的机器越多,扩容,查询写入的效率就越高。 过了一定时间后,速度竟然变慢了。 分析发现存储层存在性能瓶颈。 上图只使用了2台服务器连接数据库。 一个真正的分布式系统可能有数百甚至数千台服务器。 如果两者都连接到数据库,连接数和锁争用等问题可能会导致 SQL 性能下降。 知道。

后来发生的事情大家都知道,互联网公司开始分离读写请求,将读请求和写请求分开。

读写分离隐含着一个逻辑,即数据写入后,并不会立即使用。

从写入数据到立即使用数据有一个时间滞后。 数据从数据库同步后才会被读取。 实际统计发现,在常规应用中,90%的数据写入后不会立即使用。 当然,我这里说的是即时时间单位是ms,一般同步延迟只有几毫秒,不超过10~20ms。

然而,这种架构并没有解决书写问题。 随着业务量的增加,写入数据成为瓶颈。 分库分表应运而生,分库分表的中间件开始流行,现在基本已经成为中大型互联网公司的标配。

基本思想是按照指定的维度对数据进行分割。 更常见的是尺寸。 例如,最后2位数字可以分成数百个表。 有的还可以除以指定模数得到余数,比如除以64得到余数。 根据余数范围0-63可分为64个库。

关于分库分表,很多人都知道有两种:垂直拆分和水平拆分(上面说的垂直和水平是系统拆分,这里指的是存储)。 垂直拆分是按照业务维度进行拆分。 ,将相同业务类型的表放到一个库中,往往按照领域模型的概念进行拆分,比如订单库、用户库、产品库等。水平拆分就是将大量的数据表(库)划分为多个数据量较小的表(库)可以减少库和表的访问压力。 可以类比系统的横向和纵向分割:

水平分割 垂直分割

系统维度

添加服务器

一个大系统按照业务领域划分为多个子系统。

数据库维度

将大数据规模按照分表规则拆分为多个小表。

一个大表根据业务领域的含义被拆分为多个子表。

为什么叫横向和纵向呢?其实很容易理解。 如果你想象一个用户表中有很多字段,如下所示

垂直分割就是在中间进行垂直切割,将右边蓝色的用户信息表和绿色的订单信息表分割成两个表。 库分为用户库和订单库。

水平分割是指进行水平切割,以减少数据量。

看到这里,你是不是觉得问题已经解决了呢? 经过上面的分库、分表分库之后,如果应用层能够处理的话,数据库层确实可以达到万级的并发级别。 但要将容量提升到另一个数量级就有点困难了。

为什么? 因为一个库实例是所有应用程序共享的,即每增加一台机器,数据库连接就会相应增加。 增量至少是机器设置的最小连接数。

为什么应用程序需要连接到所有数据库实例?

答:网关层的流量可以到任何服务器。 例如,用户A的请求发送到服务器。 此时服务器必须有用户A的分片的数据库连接,否则流量要么被路由,要么执行失败。

分库分表只是解决单库单表的访问压力问题。 但由于每台服务器同时连接所有子数据库实例,到了某个阶段就无法继续扩容,因为数据库实例的连接数存在瓶颈。

如果数据库出现瓶颈怎么办?

相信聪明的你已经猜到了,那就是在应用层通过分片的方式来完成隔离。 在网关层路由流量时,将指定uid 的流量路由到指定的应用单元执行。 该应用单元的流量是内部消化的,如下图:

例如uid=,最后两位是34,属于00-49的范围。 然后用户流量直接路由到00-49应用组,所有数据交互操作都在这个单元内完成。

这样,组单元uid 00-49中的应用程序只使用00-49子库连接的数据库。 对于组单元 uid 50-99 中的应用程序也是如此。 数据库连接数直接减少一半,单位还可以拆分。 现在是 2 个单元,最多可拆分为 100 个单元。

我在这里强调单位这个词,因为这是LDC的核心概念。 我们重点关注一下unit这个词的具体含义。

Ant 中的单元有一个名为“Zone”的名称。 区内服务齐全。 例如,用户可以在Zone中完成一套完整的业务流程。 流量不需要其他Zone提供服务,有能力完成整套服务。 一套完整的服务可以在一个区域内完成。 它在逻辑上是独立的。 这样做有什么好处呢? 如果某个Zone发生故障,路由层会直接将该Zone的流量转移到其他Zone。 接受这个区域流量的其他几个区域可以进行流量共享和流量分配,非常方便。

下图是蚂蚁专区按照地域和分片的部署架构示意图。 已进行一些简化。 实际的区域部署单元会稍微复杂一些。

上面介绍的Zone能够完成uid维度的一整套业务流程。 应用程序相互依赖的服务均由该Zone提供,服务之间的调用均在该Zone内完成。 但如果你聪明的话,你可能会想到一个问题。 有些数据无法按照维度进行拆分。 如果全局只有一份怎么办? 例如,配置中心的数据集中存储。 全局配置只有一项,配置后全局生效。

其实在Ant内部,Zone分为三种:、、

:上述逻辑是自成一体的,是业务系统整体部署的最小单元。 里面部署了可以按照维度拆分的服务和库。

: 是区域。 从名称中您也知道,服务和库只会在全球部署一份副本。 一定是在某个机房里。 其他地方也会部署,但只是为了容灾,不会启用。

: 还蛮有趣的。 它为何存在? 它是为了解决缺点而创建的。 正如之前架构文章《看互联网公司如何从B站崩溃中做高可用》中提到的,跨城通话由于距离较远,非常耗时。 相对较高。 如果服务部署在上海,杭州机房的服务需要使用部署的服务,只能跨城市、跨机房调用。 一个服务很有可能会有很多次RPC调用,这肯定会非常耗时。 怎么做? ? 搭建城市之间的数据同步桥,作为桥梁,负责同步城市之前的数据。 C代表城市。

也是因为我前面提到的“写和读的时间差”。 写入的数据允许一定的延迟,并与其他数据同步。

分享