应对业务量的不断增加场景通常有两个大方向,一种是纵向扩展,也就是增加单台服务器的 CPU 计算能力、内存容量和磁盘承载能力等;另外一种是横向扩展,也就是通过增加服务器的数量来增加处理能力。前者存在业务中断和扩展上限等诸多的问题,特别是互联网业务的迅猛发展,单台服务器几乎无法满足业务负载要求,因此目前比较流行的方式横向扩展的方式。

 

1. 数据库集群

数据库的横向扩展是通过数据库集群实现的。数据库集群也有两种主要形式,一种是主备(主从)架构,也就是只有一台服务器上的数据库可以访问,另一个(多个)服务器上数据库不能访问或者只能进行读操作。另外一种是多活架构,这种架构中所有服务器都可以对外提供服务(可同时读写)。

 

当前市面上大部分数据库是主从架构,比如 MySQL 和 SQL Server 等。如图 1 是大名鼎鼎的 MySQL 数据库的主从复制原理图。主从复制是通过重放 binlog 实现主库数据的异步复制。由于从 binlog 获取数据并重放与主库写入数据存在时间延迟,因此从库的数据总是要滞后主库。这个也是主从架构的缺点,也就是无法保证数据的分布式一致性。主库宕机的情况下可能会丢失一部分数据。

 

图 1 MySQL 主从复制

 

2. 分区多活集群

多活架构是集群中的节点可以同时对外提供服务。根据集群中节点是否可以共享数据,多活架构又分为两种。一种是非共享数据的多活,该种情况下集群节点不能共享数据,每个节点负责不同的数据。比如将数据库表以主键 ID 进行划分(比如取模),不同节点负责不同的区域。目前这种多活方案可以通过数据库中间件实现,比如开源的 Mycat 等。

 

图 2 基于 Mycat 的多活架构

 

如图 2 所示是基于 Mycat 的多活数据库集群,这里面主要划分为 2 个区域,每个区域通过主备保证可用性和分摊负载。具体策略可以采用取模的方式,比如主键 ID 为 1,3,5,7... 时数据存储在左边主库中;2,4,6,8... 时数据存储在右边主库中。

 

由于数据的隔离性,上述访问存在一个主要问题就是扩容相对困难。当需要增加集群节点数量的时候,就需要重新划分数据的存储位置,从而需要做大量的数据迁移。这样,不仅仅操作复杂,而且增加了出现问题的风险。

 

3. 共享存储多活集群(Oracle RAC)

另外一种多活架构是共享存储集群架构,比较典型的就是 Oracle RAC(全称 Oracle Real Application Cluster)。在该架构中集群中多个节点运行的是同一个数据库实例,数据完全一致,并且用户层面无论从那个节点访问,获取到的数据都是相同的。如图 3 是 Oracle RAC 的示意图,通过 3 个节点构成一个集群,它们共享数据。

 

图 3 Oracle RAC 示意图

 

为了保证整个集群的可用性,Oracle RAC 在部署的时候对硬件有比较多的要求。在网络层面,Oracle RAC 总共有 3 个网络系统,分别是外部访问网络、内部私有网络和存储网络。外部访问网络不用多少,相信大家都理解。内部私有网络则主要用来进行 Oracle 集群内部使用,包括数据传输、心跳和集群管理等。这部分网络在部署的时候要求双交换机和双物理链路,保证不会因为链路故障导致集群异常。后面是存储网络,存储网络用于 RAC 集群访问存储资源,这部分也是链路冗余的。

 

 


图 4 Oracle RAC 物理部署图

 

为了更加深入的理解 Oracle RAC 我们看一下其内部软件模块的组成。整个数据库层面没有太多差异,这里面主要多出了如下内容:虚拟 IP(VIP)、ASM、Clusterware 和仲裁磁盘。这些新组件配合起来完成了 Oracle 的多活集群功能。

 

虚拟 IP 是应用访问数据库的入口,该 IP 并不与任何服务器绑定,而是可以在集群的任意服务器间漂移。由于具有这个特性,当出现服务器宕机等情况时,数据集集群可以保证通过相同的接口对外提供服务。

 


图 5 Oracle RAC 软件模块图


ASM 与 Clusterware 实现了集群管理功能,其中 ASM 实现对磁盘的管理,避免同时访问磁盘导致数据不一致的风险,而 Clusterware 则用于管理 Oracle 集群的软件进程及资源调度。

 

仲裁磁盘用于集群中服务器的异常判断,集群中的节点通过定时更新仲裁磁盘中特定区域的数据标示自身的健康状态。其它节点可以根据该数据判断该节点是否宕机。