SQL Server负载均衡;数据库集群

前言 
Internet的规模每一百天就会增长一倍,客户希望获得7天×24小时的不间断可用性及较快的系统反应时间,而不愿屡次看到某个站点“Server Too Busy”及频繁的系统故障。 
随 着业务量的提高,以及访问量和数据流量的快速增长,网络各个核心部分的处理性能和计算强度也相应增大,使得单一设备根本无法承担。在此情况下,如果扔掉现 有设备去做大量的硬件升级,必将造成现有资源的浪费,而且下一次业务量的提升,又将导致再一次硬件升级的高额成本投入。于是,负载均衡机制应运而生。 

ORACLE的“RAC”启示 
对于负载均衡,笔者经常接触的当属Oracle的负载均衡机制。下面,我们先简单了解Oracle的负载均衡的实现方案。 
Real Application Clusters是并行服务器(8i及以前版本称作Oracle Parallel Server,OPS),用来在集群环境下实现多机共享数据库,以保证应用的高可用性,同时可以自动实现并行处理及均分负载,还能实现数据库在故障时的排 错和无断点恢复。它可以自动进行负载平衡、故障修复和规划停机时间,以支持高可用性应用程序。若并行服务器中某节点失效,透明的应用程序容错能够把用户自 动转接到另一节点上继续运行,应用程序在用户没有察觉的情况下继续执行。这使周期性和非周期性发生故障的系统增大了连续可用性。进程的失效可以完全透明地 转移到另一节点上去,通过适当地配置,可以指定所有查询都在客户端进行缓存,这样它们便可以在转移后的节点上重新设置。那么在SQL Server平台上是否也可以实现类似的效果? 


728e72198ce9059c4bedbc32.jpg


1、集群的分类 
一 般来讲,集群软件根据侧重的方向和试图解决的问题,分为三大类:高性能集群(High performance cluster,HPC)、负载均衡集群(Load balance cluster, LBC),高可用性集群(High availability cluster,HAC)。 
高 性能集群(High performance cluster,HPC),它是利用一个集群中的多台机器共同完成同一件任务,使得完成任务的速度和可靠性都远远高于单机运行的效果。弥补了单机性能上的 不足。该集群在天气预报、环境监控等数据量大,计算复杂的环境中应用比较多; 
负 载均衡集群(Load balance cluster, LBC),它是利用一个集群中的多台单机,完成许多并行的小的工作。一般情况下,如果一个应用使用的人多了,那么用户请求的响应时间就会增大,机器的性能 也会受到影响,如果使用负载均衡集群,那么集群中任意一台机器都能响应用户的请求,这样集群就会在用户发出服务请求之后,选择当时负载最小,能够提供最好 的服务的这台机器来接受请求并相应,这样就可用用集群来增加系统的可用性和稳定性。这类集群在网站中使用较多; 
高 可用性集群(High availability cluster,HAC),它是利用集群中系统 的冗余,当系统中某台机器发生损坏的时候,其他后备的机器可以迅速的接替它来启动服务,等待故障机的维修和返回。最大限度的保证集群中服务的可用性。这类 系统一般在银行,电信服务这类对系统可靠性有高的要求的领域有着广泛的应用。 


2、Microsoft Cluster Server(MSCS)相对于单点来说Microsoft Cluster Server(MSCS)是一个可以提升可用性的技术,不可以负载均衡的,Microsoft称之为故障转移集群。(属于高可用集群共享磁盘架构) 


从硬件连接上看,很像Oracle的RAC,两个节点,通过网络连接,共享磁盘;事实上SQL Server数据库只运行在一个节点上,当出现故障时,另一个节点只是作为这个节点的备份; 
因为始终只有一个节点在运行,在性能上也得不到提升,系统也就不具备扩展的能力。当现有的机器不能满足应用的负载时只能更换更高配置的机器。 
升级到综合性能更强大的硬件,带来的问题是硬件的浪费,然而,单节点体系结构最终会达到一个瓶颈并无法实现进一步的有效扩展。具体表现为逐渐缩小的回报率或者价格惊人的昂贵硬件设备,系统得不到可持续的扩展。 


4、复制、订阅 
我 们知道,SQL Server 提供了复制技术(Replication),可以有多个只读服务器供查询用,这个技术可以有效缓解查询的压力。我们知道,复制、订阅是一个读写分离的技 术,数据先写到中心数据库上,写成功即返回给应用程序;通过复制将数据复制到只读的服务器,查询的时候从只读服务器查。 


这就意味着订阅端的数据和中心数据库的数据不同步,是个异步的过程,所以数据滞后严重,数据同步的实时性得不到保障,中心数据库在正常的压力下10秒左右。当访问负荷很高或者中心数据库在整理数据时,将出现大量DML操作时延迟时间比较长或者出现堵塞的情况; 
某些修改操作需要重新建立复制关系并初始化,这期间需要停止数据库的读取服务,规模越大的应用停止的时间越长,严重影响了数据库的可用性。 另外中心数据库所采用的结构还是MSCS,只是提供了一种故障转移的机制,当有一个节点出现问题后把负载转移到另一个节点上; 
结 论:从上面可以看出,在MS-SQL Server 平台上没有提供类似Oracle RAC的技术,实现不了负载均衡。数据库的高并发及横向扩展是用户经常遇到的问题,所以好多SQL Server用户遇到这样的困惑时就移植到Oracle平台上,采用RAC来解决。这将是一个即费财力又费物力、人力,同时还要面临很大风险的一个艰难过 程。 
所以说在MS-SQL Server平台上实现像Oracle RAC一样高性能、高可用性和方便扩展的集群解就成广大SQL Server用户期待的一个焦点,就目前来说,这类技术似乎只能在在一些专业研究第三方数据库集群的公司看到。 


数据库负载均衡集群的实现 
1、实现原理 
实 现数据库的负载均衡技术,首先要有一个可以控制连接数据库的控制端。在这里,它截断了数据库和程序的直接连接,由所有的程序来访问这个中间层,然后再由中 间层来访问数据库。这样,我们就可以具体控制访问某个数据库了,然后还可以根据数据库的当前负载采取有效的均衡策略,来调整每次连接到哪个数据库。好处在 两个方面:首先,它成功地将数据库放到了内网之中,更好地保护了数据库的安全性。如果数据库也在公网上,1433端口是很容易被***的,所以要保护数据库 与之的连接,就用到了中间层。它可以将数据库更加好地保护在内网。其次,对应用来说完全透明,集群暴露出来的就是一个IP ,连接数据库的所有连接都可以控制,更方便DBA对数据的管理,看哪些连接更耗费数据库资源,以便更好地优化代码。 
但 是,也有两点要注意:第一,必须要做成Windows的服务程序。Windows发展到今天,如果以一个集成的大系统来讲,做成服务程序更加稳定,也更加 安全,这样做即使用户不登录机器,也可以使用。第二,必须要使用多个中间层。从中间层的作用可以看出,它承接了数据库的所有连接,所以,一旦出了问题,就 会导致整个系统瘫痪。所以做多个中间层是必要的,这样,如果一个坏了可以登录到另一个。 
f91a5d768d3f5333b051b994.jpg


2、实现多据库数据同步 
前 端连接数据库起均衡作用的有了,下一步的工作是设置构建数据库集群。对于负载均衡,最重要的就是所有服务器的数据都是实时同步的。这是一个集群所必需的, 因为,如果数不据实时、不同步,那么用户从一台服务器读出的数据,就有别于从另一台服务器读出的数据,这是不能允许的。所以必须实现数据库的数据同步。这 样,在查询的时候就可以有多个资源,实现均衡。 
Moebius 集群采用将核心程序驻留在每个机器的数据库中的办法,这个核心程序称为Moebius 中间件,主要作用是监测数据库内数据的变化并将变化的数据同步到其他数据库中。数据同步完成后客户端才会得到响应,同步过程是并发完成的,所以同步到多个 数据库和同步到一个数据库的时间基本相等;另外同步的过程是在事务的环境下完成的,保证了多份数据在任何时刻数据的一致性。 
正因为Moebius 中间件宿主在数据库中的创新,让中间件不但能知道数据的变化,而且知道引起数据变化的SQL语句,根据SQL语句的类型智能的采取不同的数据同步的策略以保证数据同步成本的最小化。 

数据条数很少,数据内容也不大,则直接同步数据 
数据条数很少,但是里面包含大数据类型,比如文本,二进制数据等,则先对数据进行压缩然后再同步,从而减少网络带宽的占用和传输所用的时间。 
数据条数很多,此时中间件会拿到造成数据变化的SQL语句, 然后对SQL语句进行解析,分析其执行计划和执行成本,并选择是同步数据还是同步SQL语句到其他的数据库中。此种情况应用在对表结构进行调整或者批量更改数据的时候非常有用。 


Moebius中间件同步策略 
数据压缩: 
如果需要同步的数据中包含文本、二进制等大数据类型, 则先对数据进行压缩然后再同步,从而减少对网络带宽的消耗和数据在传输过程中所用的时间。尤其对于网络带宽资源非常稀缺的场景。 通过fire_compression_bytes参数进行阀值控制。 
批量执行重复性数据: 
如果需要同步的数据中包含重复性的数据,则中间件会把重复性的数据合并到一个同步命令中只执行一次,从而减少执行的次数。 
例 如:执行语句 UPDATE dbo.UserInfo SET DeleteFlag = 1 WHERE LastLoginDate < '2008-08-08' 共修改了600条数据,这600条数据的DeleteFlag列具有相同的值,中间件会把这些相同的值合并到一个同步命令中去,同步的SQL语句 为:UPDATE dbo.UserInfo SET DeleteFlag = 1 WHERE UserID IN(1, 3, 4, 5, 7, 10, 13, 15, ......, 895, 897, 899, 1000)。而不是逐条的去同步: 
UPDATE dbo.UserInfo SET DeleteFlag = 1 WHERE UserID = 1 
UPDATE dbo.UserInfo SET DeleteFlag = 1 WHERE UserID = 3 
UPDATE dbo.UserInfo SET DeleteFlag = 1 WHERE UserID = 4 






UPDATE dbo.UserInfo SET DeleteFlag = 1 WHERE UserID = 899 
UPDATE dbo.UserInfo SET DeleteFlag = 1 WHERE UserID = 1000 
该策略对数据进行批量更新、批量删除的场景下非常有用。 通过rows_in_command参数进行阀值控制。 
升级数据库锁(锁优化器) 
如 果更新的数据量非常大,SQL Server本身会对锁进行升级,将大量较细粒度的锁(例如行)转换为少量较粗粒度的锁(例如表)从而减少系统开销。中间件在同步之前先检查当前SQL Server的锁的粒度,如果锁已经升级,则中间件先对目标数据库直接进行锁升级然后再同步数据。从而避免了目标数据库锁升级的过程。通过 fire_lock_optimizer_rows 参数进行阀值控制。 

同步SQL语句(同步优化器) 
如 果更新的数据量非常大,超过了设定的阀值,同步大量的数据势必会消耗大量的网络带宽并且延长同步的时间,甚至会造成网络拥堵。这时候中间件首先获取导致数 据变化的SQL语句,分析该SQL语句的类型以及执行成本,并选择是把变化的数据同步过去还是把导致数据变化的SQL语句同步过去。该策略在对表结构进行 调整或批量更改数据的时候非常有用,大量的减少网络带宽的消耗,降低同步时间。通过fire_sync_optimizer_rows 参数进行阀值控制。 

并发执行SQL语句 
即 使使用了同步SQL语句策略,总的执行时间也相当于执行两次SQL语句的时间。如果这个时间还是不能接受。可以通过中间件提供的系统存储过程 usp_MBS_ParallelExecute在集群中的各个节点数据库中并发执行SQL语句,使执行时间降低到相当于在单机数据库中执行一次的时间。 但是要注意并不是所有的语句都适合并发执行,具体请参见usp_MBS_ParallelExecute。 


4、透明性 
中间件宿主在SQL Server数据库中,这是Moebius 的一个创新,主要是确保原有的数据库架构移植到集群架构上简单方便,避免对系统进行较大的改造。 
对开发透明: 
中间件是在数据库内部工作的,不改变SQL Server原来的应用特性,开发人员面对的还是熟悉的SQL Server数据库、SQL语句以及开发/调试工具。不需要改变原有的习惯,不需要学习新的工具。 
许多关键的数据库技术比如事务、连接池、锁、数据存储、安全等还是依靠SQL Server数据库来完成,对客户来说,无论是研发成本还是实施风险都降到最低。 
对管理透明: 
对于管理人员来说,仍然可以使用SQL Server提供的管理工具来管理数据库,可以把集群看成一个数据库来管理,系统进行了封装,感觉和使用原来的一个数据库时候一样,易用性非常好。 
对应用透明: 
对于应用程序的连接,用户只需要在应用程序连接组件中进行配置,将应用程序与数据库集群连接即可,对您的应用程序及业务没有丝毫影响。