| 网站首页 | 测试咨讯 | 新手入门 | 专注性能 | 测试技术 | 测试管理 | 测试工具 | 开发社区 | 工具下载 | 资料下载 | 测试论坛 | 

[CNTester联盟群]交流群:34446273/21968356/64461572 白盒群:18400216 自动化群:2706508 性能群:4498858 外包群:59649884 管理群(需有管理经验):64442523

新手入门
 入门指南
 经验之谈
测试咨讯
 行业新闻
 网站动态
 人才就业
 CNTester基金
 标准规范
专注性能
 性能测试知识
 性能测试工具
 程序设计性能
 数据库性能
 Web应用服务器性能
 操作系统性能
 服务器与网络性能
测试技术
 用例设计
 性能测试
 自动化测试
 Web测试
 面向对象测试
 综合技术
 阶段性测试
 行业类测试
测试管理
 项目管理
 项目案例
 质量管理
 软件过程
测试工具
 Mercury系列
 Rational系列
 测试管理工具
 性能测试工具
 功能测试工具
 单元测试工具
 其它测试工具
开发社区
 Java技术
 DotNet技术
 C技术
 数据库技术
 操作系统
 服务器与中间件
工具下载
 测试工具
 开发工具
 企业工程
 网络通信
 媒体桌面
 游戏娱乐
 其他工具
资料下载
 测试资料
 程序设计
 数据库
 操作系统
 应用服务器
 电子期刊
 其他资料
 
 
您现在的位置: 中国测试员网站 >> 专注性能 >> 程序设计 >> Java性能 >> 文章正文
  [组图]高速缓存和连接池对访问数据库性能的影响         ★★★ 【字体:
高速缓存和连接池对访问数据库性能的影响
作者:FoolsGar…    文章来源:IBM developerWorks    点击数:    更新时间:2007-8-30    
介绍高速缓存和连接池的基础上,给出解决数据库性能问题的一些有用办法。

初识高速缓存和连接池

设想这样一种情形:你突然口渴,需要一杯水来缓解,从心情上来讲,当然是越快越好了。通常,一杯水的产生包括从水源(井水、河水或江水、甚至海水等)抽取,通过管道传输和设备净化,才到达你饮水的容器中。上述过程是必须的,但并不是每一杯水的产生都必须把上述过程重复一次。你可以用一个大一点的容器(例如缸或罐等)来盛大量的水,喝水之前分到杯子小部分中即可,你的代价只是把水从缸转移到杯子;你还可以在大量用水(例如洗澡或洗衣服等)时,只需打开水阀,而不必临时铺设通往水源的管道和购买净化水的设备。因为水是人们生活不可缺少的东西,每时每刻都在被大量地使用,而且物理本质也完全相同,所以政府会铺设管道和建设水处理站,完成那些比较困难的工作,达到资源共享的目的,而你也可针对自己的需求,用容器来盛那些具有特定用途的水。本文将要和你讨论的高速缓存和连接池与上述特定容器和传输管道有很多相似之处,它们都达到了同一个目的:在满足用户意愿的前提下,尽可能地共享资源,以提高整个系统的性能。

高速缓存和连接池是数据访问中的重要技术,某些情况下的应用对访问数据库的性能有巨大的提高,而且都得到了数据库业界的普遍支持。前者由DBMS厂商针对自己的数据库实现,提供可供用户配置的方案;后者是JDBC的一个标准接口,由支持J2EE技术的应用服务器厂商提供具体的实现,而你的Java程序代码无需更改。本文将向你简单介绍高速缓存和连接池的概念和机制,并以PointBase数据库为例向你展示高速缓存的应用,而一个简单的连接池应用场景将向你描述应用的条件和提高的性能。


 

Cache(高速缓存)和Connection Pool(连接池)的概念和机制

它们不是数据库独有的技术,但却得到数据库业界的普遍支持,并在其它数据存取和对象复用领域有很多类似的应用。

Cache(高速缓存)

作为个人计算机的日常使用者,你肯定听说过这些名词:Cache(高速缓存)、Memory(内存)、Hard disk(硬盘)。它们都是数据存取单元,但存取速度却有很大差异,呈依次递减的顺序。对于CPU来说,它可以从距离自己最近的Cache高速地存取数据,而不是从内存和硬盘以低几个数量级的速度来存取数据。而Cache中所存储的数据,往往是CPU要反复存取的数据,有特定的机制(或程序)来保证Cache内数据的命中率(Hit Rate)。因此,CPU存取数据的速度在应用高速缓存后得到了巨大的提高。

对于数据库来说,厂商的做法往往是在内存中开辟相应的区域来存储可能被多次存取的数据和可能被多次执行的语句,以使这些数据在下次被访问时不必再次提交对DBMS的请求和那些语句在下次执行时不必再次编译。



因为将数据写入高速缓存的任务由Cache Manager负责,所以对用户来说高速缓存的内容肯定是只读的。需要你做的工作很少,程序中的SQL语句和直接访问DBMS时没有分别,返回的结果也看不出有什么差别。而数据库厂商往往会在DB Server的配置文件中提供与Cache相关的参数,通过修改它们,可针对我们的应用优化Cache的管理。下图是在Win2K中配置MS Access数据源的界面,在"驱动程序"部分你可设置的页超时和缓冲区大小就是和Cache有关的参数。在后面的讨论中,我将展示一个更复杂的数据库,向你解释Cache对访问数据库性能的影响和如何寻找最优的配置方案。



Connection Pool(连接池)

池是一个很普遍的概念,和缓冲存储有机制相近的地方,都是缩减了访问的环节,但它更注重于资源的共享。下图展示了建立"调制解调器池"以共享调制解调器资源的VPN拨号方案:



对于访问数据库来说,建立连接的代价比较昂贵,因此,我们有必要建立"连接池"以提高访问的性能。我们可以把连接当作对象或者设备,池中又有许多已经建立的连接,访问本来需要与数据库的连接的地方,都改为和池相连,池临时分配连接供访问使用,结果返回后,访问将连接交还。

JDBC 1.0标准及其扩展中没有定义连接池,而在JDBC 2.0标准的扩展中定义了与连接池相关的接口。与接口对应的类由应用服务器厂商实现,你可在对服务器的管理过程中调节某个数据库连接池的参数。下图简略地描述了连接池的运行机制:




 

高速缓存的参数设定

在PointBase数据库DB Server的配置参数列表中,我们可以找到这几个参数:cache.checkpointinterval、cache.size、SQLCaching.size等。下表是对各个参数的描述:

参数名 参数描述
cache.checkpointinterval 检查点的时间间隔
cache.size 高速缓存的最大页数(素数时,性能最好)
SQLCaching.size 高速缓存中SQL语句的个数

对于cache.checkpointinterval来说,和前面Access界面中的页超时是一个概念,它指定了页面内容更新的时间间隔,这取决于你的应用对时效性的要求程度。

对于cache.size来说,指定了页面的个数,一般应设定为符合你查询结果的需求。至于为何是素数,我也纳闷,不过还是遵照厂商的指示吧。

对于SQLCaching.size来说,指定了存储的经过编译的SQL语句的个数,你可以把它设定为0,从而取消这个选项。

使用Cache后,性能到底有多大提高?我打开PointBase的Console通过JDBC驱动访问Server,将SQL菜单下的Timing Mode选上,以显示各个步骤的耗费时间。执行语句是:

SELECT * FROM PRODUCT_TBL

第一次访问,总计耗时1082毫秒,而编译耗时771毫秒。

紧接着的第二次访问,总计耗时仅为160毫秒,而编译耗时为0。

再接着的第三次访问,总计耗时仅为91毫秒,编译耗时也为0。

关闭Console,等待超过30秒之后,重新开启Console,执行相同的语句,总计耗时210毫秒,编译耗时为20毫秒。

自等待超过30秒之后,执行语句,总计耗时101毫秒,编译耗时为0。

由此可以看出,高速缓存的应用大大提高了访问数据库的性能,而其参数的设定则要依据前面对它们的描述来进行,需要你仔细阅读数据库的配置文档。


 

连接池的设置和应用

我选择IBM公司的应用服务器平台WebSphere来给大家演示连接池的设置,使你面对友好的Web界面,可以体验到非常简易的操作场景。

首先,我们进入WebSphere的管理控制台,这是一个非常漂亮的Web界面:



紧接着,我选定一个数据源:Session Persistence datasource,就可看到这个数据源的属性配置了。在这儿,仅仅列举和连接池有关的属性:

Minimum Pool Size 池中保持的连接的最小数目;有新的请求,且没有激活连接可供使用时,池中连接数将增大,到最大连接数为止
Maximum Pool Size 池中保持的连接的最大数目;当这个数目达到,且没有激活连接可供使用时,新的请求将等待
Connection Timeout 当连接数达到最大值,且激活连接都在被使用时,新的请求等待的时间
Idle Timeout 连接可在池中闲置的时间;超过将释放资源,到最小连接数为止
Orphan Timeout 连接在被应用控制时,可闲置的时间;超过将返回池中

你可以根据需要来修改这些数值,以满足你的应用需要。接下来,我们讨论一下连接池的应用。

EJB访问数据库(场景1,使用JDBC 1.0)
import java.sql.*;
import javax.sql.*;
...
public class AccountBean implements EntityBean {
...
public Collection ejbFindByLastName(String lName) {
      try {
            String dbdriver = new initialContext().lookup("java:comp/env/DBDRIVER").toString();
            Class.forName(dbdriver).newInstance();
            Connection conn = null;
            conn = DriverManager.getConnection("java:comp/env/DBURL", "userID", "password");
            ...
            conn.close();
      }
...
}

如果EntityBean是一个共享组件,那么每次客户请求时,都要建立和释放与数据库的连接,这成为影响性能的主要问题。

EJB访问数据库(场景2,使用JDBC 2.0)
import java.sql.*; 
import javax.sql.*; 
// import here vendor specific JDBC drivers
public ProductPK ejbCreate() {
      try {
// initialize JNDI lookup parameters
            Context ctx = new InitialContext(parms);
...
            ConnectionPoolDataSource cpds = (ConnectionPoolDataSource)ctx.lookup(cpsource); 
...
// Following parms could all come from a JNDI look-up 
            cpds.setDatabaseName("PTDB"); 
            cpds.setUserIF("XYZ"); 
...
            PooledConnection pc = cpds.getPooledConnection(); 
            Connection conn = pc.getConnection(); 
...
// do business logic
            conn.close();
      }
...
}

EJB组件利用JNDI的lookup()方法定位数据库的连接池资源,利用getConnection()方法得到已经打开的数据库连接,而用close()来释放连接,放回池中。因此,与场景1相比,少了与数据库建立物理连接的损耗。对于原本要频繁打开和关闭物理连接的应用来说,通过这种建立逻辑连接并复用的方法,性能肯定能够得到大幅度提高。


 

性能问题的深远思索

性能问题并不局限于数据库的应用上,而是存在于每个软件系统中。我们希望软件系统付出的最小,而获得的最大,因而无时无刻不在优化它们。通过《Java程序访问数据库的速度瓶颈问题的分析和解决》和本文,我对Java程序访问数据库的性能问题做了分析,并提供了优化Java程序的解决方案,希望对你有所帮助。

也许你会关心碰到类似的性能问题时应如何分析和解决,我就针对此次探讨"访问数据库的速度瓶颈"问题的过程中碰到的难题、网友的意见和自己的体会,作一个关于"方法论"的经验总结,希望能够抛砖引玉,更好地解决类似的问题。


 

解决性能问题的几条经验

  1. 不要让硬件的低配置成为软件正常运行的障碍,后者有升级前者的需求,请立即满足;经常碰到这样的问题"P166+64M的机子跑Win2K+MySql+JBoss,能跑么?"我在回答"可以"的同时只有对着屏幕发呆了。
  2. 尽量使用商业软件,并享受良好的售后技术支持;如果你没有黑客精神,请不要使用自由软件。
  3. 分析好自己的问题,也许它的本质和他人的不同;没有一把钥匙可打开的任一把锁。
  4. 确定瓶颈环节的位置;解决了瓶颈问题,往往整个的性能问题就解决了,千万不要抓着边缘的问题不放。
  5. 将瓶颈环节细分为多个顺序的流程,用逐个替代的方法来试探瓶颈的核心位置;细分问题使你都问题有更进一步的了解。
  6. 做自己能做的和该做的事情,始终面向自己的现实问题;不要尝试那些应该由厂商解决的问题(例如,自己写个JDBC驱动)。
  7. 他人的方案只供自己参考,解决要靠自己思考;你我应用的情形不同,应用解决方案要在理解他人的方案之后。
  8. 观察新技术,应用新技术;它往往包含了前人对问题解决的思路,只是对你来说不可见。
  9. 问题得到解决后,立即罢手,并汇报结果;在现实问题得到解决后,没有必要花费精力在非核心的问题上,也许它们永远不会被碰到,不要假想问题让自己解决。

上述经验为个人即兴的总结,并未有严谨的逻辑推导,仅代表我解决技术问题的思路,供你碰到类似问题时参考。

可以提前告诉大家的是,下一篇文章我将把主题转移到JDO的介绍和讨论上。这个陌生的API已经进入Final Draft了,可它到底能够给数据存取带来什么好处,和JDBC有什么关联的地方,《JDO(Java Data Object)的发展和介绍》将向你娓娓道来。



参考资料



关于作者

曾任水木清华BBS的Java技术和嵌入式系统的讨论区负责人,对Java技术有很深的钻研和丰富的教学经历
曾在清华大学微电子学研究所从事Java智能卡微处理器的研究和开发
现任水木清华BBS的自由与协作的讨论区负责人,探讨网络协作的开发模式
参与JXTA项目的探讨,并为JXME(JXTA+J2ME)项目的核心成员,致力于推动P2P在嵌入式(尤其是无线网络)领域的发展
致力于国内Java技术的推广宣传和普及教育

文章录入:root    责任编辑:root 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
     
    最新热点 最新推荐 相关文章
    · mysql优化基础
    · MySQL服务器安装完之后如何调节性能
    · Mysql数据库管理系统优化方案
    · MySQL Performance Tuning Primer Script
    · MySQL 性能跟踪语句
    · Linux 和对称多处理
    · 应用与数据库性能测试解决方案,QUEST SO
    · 负载、性能测试和容量测试的关系和区别
    · LoadRunner监控Windows和Linux常见问题
    · 31个用来测试网站各项性能的免费工具
    · 应用与数据库性能测试解决方案,QUEST SO
    · 研究项目: JBoss架构分析
    · 如何通过 20% 的工作获得 80% 的性能改善
    · Linux 调度器内幕
    · 在 Linux 上利用数据分区功能提高可伸缩性
    · 降低 Linux 内存开销
    · Linux 和对称多处理 在 SMP 系统上发挥 L
    · 如何提高系统性能指标
    · Java 优化技术 充分挖掘 Java 应用程序性
    · 高速缓存和连接池对访问数据库性能的影响
    31个用来测试网站各项性能的
    研究项目: JBoss架构分析
    Rational LoadTest 性能测试
    loadrunner 负载测试计划
    IBM Rational助您轻松完成基
    如何通过 20% 的工作获得 80
    基于 WebSphere Application
    Linux 调度器内幕
    在 Linux 上利用数据分区功能
    使用异步 I/O 大大提高应用程
     
     
     
    ======> [CNTester联盟群]交流群:34446273/21968356/64461572 白盒群:18400216 自动化群:2706508 性能群:4498858 外包群:59649884 管理群(需有管理经验):64442523
    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 | 

    Copyright@2007 by CNTester.com 中国测试员网站 桂ICP备07005590

    本站为开源免费网站,非商业赢利性组织。本站文章部分从网络搜索获取,如果您认为某些侵犯了您的权益,麻烦您联系本站,我们会尽快删除相关内容,同时也希望您的谅解,我们的初衷是为了让更多人去学习这方面的知识,让行业有更好的发展。

    联系电话: 15021358905