业务背景

当今世界是一个信息化的世界,我们的生活中无论是生活、工作、学习都离不开信息系统的支撑。

而信息系统的背后用于保存和处理最终结果的地方就是数据库。因此数据库系统就变得尤为重要,这意味着如果数据库如果面临问题,则意味着整个应用系统也会面临挑战,从而带来严重的损失和后果。

如今“大数据”这个词已经变得非常流行,虽然这个概念如何落地不得而知。但可以确定的是,随着物联网、移动应用的兴起,数据量相比过去会有几何级的提升,因此数据库所需要解决的问题不再仅仅是记录程序正确的处理结果,还需要解决如下挑战:

当数据库性能遇到问题时,是否能够横向扩展,通过添加服务器的方式达到更高的吞吐量,从而充分利用现有的硬件实现更好的投资回报率。

是否拥有实时同步的副本,当数据库面临灾难时,可以短时间内通过故障转移的方式保证数据库的可用性。此外,当数据丢失或损坏时,能否通过所谓的实时副本(热备)实现数据的零损失。

数据库的横向扩展是否对应用程序透明,如果数据库的横向扩展需要应用程序端进行大量修改,则所带来的后果不仅仅是高昂的开发成本,同时也会带来很多潜在和非潜在的风险。

面对上述挑战一个显而易见的办法是将多个服务器组成一组集群,这样一来就可以充分利用每一台服务器的资源并将客户端负载分发到不同服务器上,随着应用程序负载的增加,只需要将新的服务器添加到集群即可。

本篇文章将对集群的概念、形式以及目前主流的数据库集群技术进行探讨。

数据库集群的形式

数据库的集群和扩展不像应用程序扩展那样容易,因为从数据库端来说,一旦涉及到了集群,往往会涉及到数据库层面的同步,因此从是否存在数据冗余这个角度来讲,我们可以从大面上把数据库集群分为以下形式:

  • Shared Everthting

  • Shared Disk

  • Shared Nothing

  • Shared Memory

shared memory

体系结构的cpu之间通过主存进行通讯,具有很高的效率;但当更多的cpu被添加到主机上时,内存竞争contetion就成为瓶颈,cpu越多,瓶颈越厉害。

Shared disk也存在同样问题,因为磁盘系统由 Interconnection Network 连接在一起。

Shared memory 和 shared disk 的基本问题是 interference:当添加更多的cpu,系统反而减慢,因为增加了对内存访问(memroy access)和网络带宽(network bandwidth)的竞争。

这样 shared nothing 体系得到了广泛的推广。

Shared Everthting

一般是针对单个主机,完全透明共享CPU/MEMORY/IO,并行处理能力是最差的,典型的代表SQLServer

Shared Disk

各个处理单元使用自己的私有 CPU和Memory,共享磁盘系统。

典型的代表Oracle Rac,它是数据共享,可通过增加节点来提高并行处理的能力,扩展能力较好。

其类似于SMP(对称多处理)模式,但是当存储器接口达到饱和的时候,增加节点并不能获得更高的性能 。

Share-Disk 架构是通过多个服务器节点共享一个存储来实现数据库集群,两台机器最简单的 Share-Disk 架构如图1所示。

Share-Disk-Struct

双活与单活

在此基础之上,Share-Disk架构又分为单活和双活。

双活即为集群中的每一个节点都可以同时对外提供服务,而单活为集群中只有一个节点可对外提供服务,集群中的其他服务器作为冗余在“活”的节点出现故障时接替该服务器成为对外提供服务的节点。

该类架构最典型的产品就是SQL Server Failover Cluster(SQL Server故障转移集群)、NEC的EXPRESSCLUSTER、ROSE的ROSE HA。

弊端

这种方式的弊端也是显而易见的,如下:

  1. 硬件资源的严重浪费,同一时间集群中只有一台服务器活着,其他服务器只能作为冗余服务器。

  2. 集群无法提升性能,因为只有一台服务器可用

  3. 存储方面存在单点故障,除非在存储层级保证高可用,通常需要昂贵的SAN存储。

因此该类方案仅仅可以做到服务器层面的高可用,无法带来性能的提升,也无法解决存储单点故障的问题。因此如果不搭配其他高可用或负载均衡的技术,存在的意义并不是很大。

双活

另一类技术是 Share-Disk 中的双活的技术,与单活技术不同的是,双活的技术虽然也是共享磁盘,但集群中的所有节点都可以对外提供服务,典型的产品就是Oracle的RAC。

RAC 的技术性非常的高,因此需要水平比较高的人来运维系统。

RAC 设计的初衷并不是为了性能,而是为了高可用和可扩展性,如果应用程序不是针对RAC架构设计和开发的,则将应用程序迁移到RAC上由于block contention (block busy waits)可能会导致性能的急剧下降,并且节点越多性能下降越明显。

Shared Nothing

各个处理单元都有自己私有的CPU/内存/硬盘等,不存在共享资源,类似于MPP(大规模并行处理)模式,各处理单元之间通过协议通信,并行处理和扩展能力更好。

典型代表 DB2 DPF 和 hadoop,各节点相互独立,各自处理自己的数据,处理后的结果可能向上层汇总或在节点间流转。

我们常说的 Sharding 其实就是Share Nothing架构,它是把某个表从物理存储上被水平分割,并分配给多台服务器(或多个实例),每台服务器可以独立工作,具备共同的schema,比如MySQL Proxy和Google的各种架构,只需增加服务器数就可以增加处理能力和容量。

服务架构

Share-Nothing 架构又分为两种,首先是分布式架构。将数据库中的数据按照某一标准分布到多台机器中,查询或插入时按照条件查询或插入对应的分区。

另一种是每一个节点完全独立,节点之间通过网络连接,通常是通过光钎等专用网络。

如图 2 所示。

服务架构

在 Share-Nothing 架构中,每一个节点都拥有自己的内存和存储,都保留数据的完整副本。

非否负载均衡

通常来说,又可以分为两种,可以负载均衡和不可以负载均衡。

首先谈谈不可负载均衡的集群,在不可负载均衡的技术中,集群中的节点会被分为主节点和辅助节点,主节点向外提供服务,辅助节点作为热备(二阶段事务提交)或暖备(不需要保证事务同步),同时有可能使得辅助节点提供只读的服务。

使用这个架构的技术包括:SQL Server AlwaysOn,SQL Server Mirror,Oracle Data Guard这种架构带来的好处包括:

优点

辅助节点数据和主节点保持同步或准同步,当搭配第三方仲裁后,可以实现自动的故障转移,从而实现了高可用

辅助节点由于和主节点完全独立且数据同步或准同步,因此主节点出现数据损坏后,可以从辅助节点恢复数据(自动或手动)

由于 Share-Nothing 架构使用了本地存储(或SAN),相较于 Share-Disk 架构在慢速网络时有非常大的性能优势

弊端

当然,弊端也显而易见,因为辅助节点无法对外提供服务或只能提供只读服务,因此该类集群的弊端包括:

  • 扩展能力非常有限

  • 对性能没有提升,因为涉及到各节点的数据同步,甚至带来性能的下降

  • 辅助节点如果可读,虽然提升性能,但需要修改前端应用程序,对应用程序不透明

负载均衡

另一类Share-Nothing架构中,是允许负载均衡的。

所谓负载均衡就是就是将对数据库的负载分布到集群中的多个节点上,在集群中的每一个节点都可以对外提供服务,从而达到更高的吞吐量,更好的资源利用率和更低的响应时间。

前端通过代理进行调度。

使用该类架构的技术包括:MySQL上的Amoeba(架构如图3,摘自MySQL大师陈畅亮的博客:http://www.cnblogs.com/gaizai/archive/2012/06/12/2546755.html),MySQL上的HA Proxy(如图4所示),格瑞趋势(www.grqsh.com)在SQL Server上的Moebius集群(如图5所示)。

图3.Amoeba

HA Proxy

Moebius 集群

优点

可负载均衡的 Share-Nothing 架构的好处是每台服务器都能提供服务,能充分利用现有资源,达到更高的吞吐量。

其中 Amoeba 中可能会涉及到数据分片,数据分片的好处是对于海量数据的处理更加高效,但同时也引入了其他问题,比如说需要应用程序端对应数据分片进行调整、跨分片节点查询的处理问题、每一个数据分片节点是否能够承受各自业务负载的高峰问题等。

该类架构需要实施的人员水平比较高,且需要应用层面做调整,因此更适合于互联网企业。

另一类不涉及到数据分片的架构,比如一类可以使用组合方案,比如说Oracle RAC+F5。

另一类是使用单个厂商提供的方案,比如说SQL Server上的Moebius。

这类方案集群中的每个节点都会对外提供服务,因此有如下好处:

  • 由于每一个节点都可以对外提供服务,因此可以提升性能

  • 扩展性得到提升,可以通过向集群添加节点直接进行Scale-Out扩充

  • 由于前端应用通过代理连接到集群,而集群中的每一个节点都保持完整的数据集,因此不存在分片不到位反而造成性能下降的问题,因此对应用程序端完全透明

但相比较于 MySQL 的数据分片,该类方案的弊端也显而易见,因为每一个节点都需要完整的数据集,因此需要占用更多的存储空间。

参考资料

Shared Everything和share-nothing区别

GreenPlum学习之(Share-nothing)架构