SQL Server 2005实现负载均衡
前言
Internet的规模每一百天就会增长一倍,客户希望获得7天×24小时的不间断可用性及较快的系统反应时间,而不愿屡次看到某个站点“Server Too Busy”及频繁的系统故障。
随着业务量的提高,以及访问量和数据流量的快速增长,网络各个核心部分的处理性能和计算强度也相应增大,使得单一设备根本无法承担。在此情况下,如果扔掉现有设备去做大量的硬件升级,必将造成现有资源的浪费,而且下一次业务量的提升,又将导致再一次硬件升级的高额成本投入。于是,负载均衡机制应运而生。
ORACLE的“RAC”启示
对于负载均衡,笔者经常接触的当属Oracle的负载均衡机制。下面,我们先简单了解Oracle的负载均衡的实现方案。
Real Application Clusters是并行服务器(8i及以前版本称作Oracle Parallel Server,OPS),用来在集群环境下实现多机共享数据库,以保证应用的高可用性,同时可以自动实现并行处理及均分负载,还能实现数据库在故障时的排错和无断点恢复。它可以自动进行负载平衡、故障修复和规划停机时间,以支持高可用性应用程序。若并行服务器中某节点失效,透明的应用程序容错能够把用户自动转接到另一节点上继续运行,应用程序在用户没有察觉的情况下继续执行。这使周期性和非周期性发生故障的系统增大了连续可用性。进程的失效可以完全透明地转移到另一节点上去,通过适当地配置,可以指定所有查询都在客户端进行缓存,这样它们便可以在转移后的节点上重新设置。那么在SQL Server平台上是否也可以实现类似的效果?
Microsoft Cluster Server
Microsoft Cluster Server(MSCS)相对于单点来说,Microsoft Cluster Server(MSCS)是一个可以提升可用性的技术,不可以负载均衡的,Microsoft称之为故障转移集群。(属于高可用集群共享磁盘架构)
从硬件连接上看,很像Oracle的RAC,两个节点,通过网络连接,共享磁盘;事实上SQL Server数据库只运行在一个节点上,当出现故障时,另一个节点只是作为这个节点的备份;
因为始终只有一个节点在运行,在性能上也得不到提升,系统也就不具备扩展的能力。当现有的机器不能满足应用的负载时只能更换更高配置的机器。
升级到综合性能更强大的硬件,带来的问题是硬件的浪费,然而,单节点体系结构最终会达到一个瓶颈并无法实现进一步的有效扩展。具体表现为逐渐缩小的回报率或者价格惊人的昂贵硬件设备,系统得不到可持续的扩展。
SQL Server 2005镜像和快照
镜像是SQL Server 2005中的一个主要特点,目的是为了提高可用性,同时和MSCS相比,用户实现SQL Server的高可用更容易了,不需要共享磁盘柜,也不受地域的限制。共设了三个服务器,第一是工作数据库(Principal Datebase),第二个是镜像数据库(Mirror),第三个是监视服务器(Witness Server)
在可用性方面有了一些保证,但仍然是单点工作;在扩展和性能的提升上依旧没有什么帮助。
数据库快照是SQL Server 2005中引入的另一项特性。快照是某一个时间点上的数据库的克隆。只要对镜像数据库进行了快照,就可以让用户查询快照。快照的生成通常只需要几秒钟,因为它实际上在这个过程中并没有拷贝任何数据。因此,要把负载分布到主服务器和备用服务器上,就可以将数据库做镜像,然后阶段性地对备份服务器进行快照。而且还可以使用快照在主服务器上进行报告。
尽管快照是可以为一些静态系统的提供查询,如报表业务等, 但是由于是快照,实时性就非常差,所以在使用上大大受到限制。
复制、订阅
我们知道,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发展到今天,如果以一个集成的大系统来讲,做成服务程序更加稳定,也更加安全,这样做即使用户不登录机器,也可以使用。第二,必须要使用多个中间层。从中间层的作用可以看出,它承接了数据库的所有连接,所以,一旦出了问题,就会导致整个系统瘫痪。所以做多个中间层是必要的,这样,如果一个坏了可以登录到另一个。
2、实现多据库数据同步
前端连接数据库起均衡作用的有了,下一步的工作是设置构建数据库集群。对于负载均衡,最重要的就是所有服务器的数据都是实时同步的。这是一个集群所必需的,因为,如果数不据实时、不同步,那么用户从一台服务器读出的数据,就有别于从另一台服务器读出的数据,这是不能允许的。所以必须实现数据库的数据同步。这样,在查询的时候就可以有多个资源,实现均衡。
Moebius集群采用将核心程序驻留在每个机器的数据库中的办法,这个核心程序称为Moebius 中间件,主要作用是监测数据库内数据的变化并将变化的数据同步到其他数据库中。数据同步完成后客户端才会得到响应,同步过程是并发完成的,所以同步到多个数据库和同步到一个数据库的时间基本相等;另外同步的过程是在事务的环境下完成的,保证了多份数据在任何时刻数据的一致性。
正因为Moebius 中间件宿主在数据库中的创新,让中间件不但能知道数据的变化,而且知道引起数据变化的SQL语句,根据SQL语句的类型智能的采取不同的数据同步的策略以保证数据同步成本的最小化。
数据条数很少,数据内容也不大,则直接同步数据
数据条数很少,但是里面包含大数据类型,比如文本,二进制数据等,则先对数据进行压缩然后再同步,从而减少网络带宽的占用和传输所用的时间。
数据条数很多,此时中间件会拿到造成数据变化的SQL语句, 然后对SQL语句进行解析,分析其执行计划和执行成本,并选择是同步数据还是同步SQL语句到其他的数据库中。此种情况应用在对表结构进行调整或者批量更改数据的时候非常有用。
3、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 = 999
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提供的管理工具来管理数据库,可以把集群看成一个数据库来管理,系统进行了封装,感觉和使用原来的一个数据库时候一样,易用性非常好。
对应用透明:
对于应用程序的连接,用户只需要在应用程序连接组件中进行配置,将应用程序与数据库集群连接即可,对您的应用程序及业务没有丝毫影响。