当你在设计一个数据库应用程序时,有时你可能觉得数据库连接类型并不重要,如果真这样的话你就大错特错了,下面列举出一些原因说明连接类型为什么是如此重要:
◆相对数据库应用程序执行的其它任务而言,创建数据库连接是最消耗系统资源的了
◆打开数据库连接时在服务器端和客户端消耗的内存都是比较多的
◆建立一个连接时需要在服务器和客户端之间往返多次
◆连接打开过多可能造成内存不足,引起从内存中换页转移到磁盘上换页,这样性能就会显著下降
◆以目前流行的架构,大多数应用程序都是使用连接池,这样性能会有所提升,但许多时候连接池调整不好也会引起性能显著下降,连接池的设计、调整和监控难度都比较大
实现连接的步骤如下:
◆从连接池获得一个连接
◆按需要一次只创建一个连接
正确的决策主要依赖于数据库服务器的CPU和内存条件。
为什么连接开销比较大?
开发人员经常认为建立一个数据库是一个简单的要求,不就是在数据库服务器和初始化用户之间的一个网络往返吗,但实际上,一个数据库连接在驱动和数据库服务器之间有多次网络往返,例如,当某个驱动连接到Oracle或Sybase时,这个连接会有7到10和网络往返,执行了一系列的动作:
◆校验用户的身份证书
◆在数据库驱动期望的代码页设置和数据库可用的代码页设置之间进行协商(如果必要的话)
◆获取数据库版本信息
◆确定用于通信的最理想的数据库协议包大小
◆设置会话设置
此外,数据库管理(开发人员承担数据库管理员职责时的最佳做法)系统要确定建立连接使用的资源,包括性能开销较大的磁盘I/O和内存分配,你可能会认为将应用程序部署到数据库服务器上会消除网络往返,在大多数情况下这并不现实,因为现实世界中大部分企业并不会这么干,它们有很多的应用程序,有很多的数据库,此外,数据库服务器都会为数据库系统进行精心的性能调整,一般不会为不同的应用程序进行调整,即使可以在一台机器上安装数据库和应用程序,但这样也会有单点故障的隐患。
使用连接池
连接池是一个和多个可重复使用的物理数据库连接的缓存,连接池可以显著提高性能,因为重复使用连接可以有效减少建立物理连接的系统开销,这里必须要说明的是你的数据库服务器必须要有足够的内存来管理连接池中的连接。
我们讨论的重点是客户端连接池(由数据库驱动和应用程序服务器提供的连接池)而不是服务器端的连接池(由数据库管理系统提供的连接池),有些数据库管理系统提供的连接池要和客户端连接池一起工作,虽然不同的服务器端连接池各有特色,但总体目标都是为了消除建立和移除连接时数据库服务器的系统开销。和客户端连接池不一样,服务器端连接池不会优化到应用程序的网络往返。
正如我们在前面提到的,连接到数据库的系统开销是比较大的,因为数据库驱动的资源分配(在驱动和数据库之间的网络往返)和数据库服务器上的资源分配开销都比较大,客户端连接池只能解决数据库服务器上自由分配的问题。
连接池如何工作
在连接池环境中,一旦建立了初始化物理连接,它就很可能在环境的生命周期内都不会关闭,即当应用程序断开连接后,物理连接不会关闭,相反,它仍然存在于连接池中,可以被重复使用,因此重新建立连接的速度就更快。下面对连接池如何工作做一个简单的介绍:
◆当应用程序或应用程序服务器启动时,连接池中开始进驻连接;
◆应用程序产生一个连接请求;
◆由驱动或连接池管理器(依赖于你的架构)从连接池中分配一个连接给应用程序,不用再建立新的连接,这意味着在驱动和服务器之间不会产生网络往返,因为池中的连接是可用的,因此连接速度就更快了;
◆应用程序连接到数据库;
◆当连接关闭时,它被放回连接池中。
什么时候不使用连接池
有些应用程序不适合使用连接池,如果你的应用程序具有下列特征就不适合使用连接池,实际上,在这些应用程序上强制使用连接池反而会导致性能下降:
◆应用程序每天会重新启动多次:这通常出现在没有使用应用程序服务器的架构中,依赖于连接池的配置,应用程序每次启动时可能都会向连接池写入一条记录,这样反而增加了连接池的系统开销;
◆单用户应用程序,如报表书写程序:如果你的应用程序只需要为一个用户建立一个连接,这个时候使用连接池就显得多余了;
◆运行单用户批处理作业的应用程序,如每日/周/月报告程序:连接池并不适合于批处理作业应用程序,因为批处理作业往往只有一个连接,而且批处理作业往往是在业务低谷期间执行的。
当你的应用程序没有使用连接池时,最好不要在执行SQL语句时频繁地连接和断开连接,因为每次连接都会产生5-10次网络请求。
设计连接
我们以一个实际例子来说明该如何设计数据库连接,环境详细情况如下:
◆环境包括的中间层必须支持20-100个并发的数据库用户,性能是关键
◆中间层和数据库服务器上CPU和内存都是充足的
◆数据库是Oracle,SQL Server,Sybase或DB 2
◆应用程序使用的API是ODBC,JDBC或ADO.NET
◆数据库服务器有25个连接许可
下面是一些可行的解决方案:
◆解决方案1:使用连接池,最大支持20个连接,每个语句一个连接
◆解决方案2:使用连接池,最大支持5个连接,每5个语句1个连接
每5-25个语句使用一个连接
这个例子中最关键是中间层和数据库服务器要有足够的CPU和内存容量,同时数据库服务器要有足够的许可,其它信息都与数据库连接设计没什么关系。
解决方案1是最佳的,它比其它两个方案都执行得要好,因为每个连接执行一个语句速度更快,解决方案2和3的架构都是多个语句使用一个连接,单个连接会成为瓶颈。
小结
许多因素都会影响到性能,有些可能超出了你的控制范围,但经过精心设计应用程序和中间层配置,可以使性能趋于理想状态,在设计应用程序时建议最好使用数据库连接池或按需要一次创建一个连接。
【编辑推荐】