| 免费下载:IBM® Informix® 11.7 试用版(包括 Ultimate Edition、Developer Edition 和 Innovator-C Edition) |
|---|
| 下载更多的 IBM 软件试用版,并加入 IBM 软件下载与技术交流群组,参与在线交流。 |
想要不更改代码就能获得显著的性能改进?这是缓存的目标所在。但它真能实现这个目标么?OpenJPA 是一个 Apache 持久化项目。OpenJPA 的一个优秀特性是让您在无需改变应用程序代码的情况下即可使用 Java Cache 加速查找并减少后端数据库上的负载。本文将向您展示如何安装、配置和试用 IBM WebSphere eXtreme Scale (XS) 产品与 OpenJPA 。而这个实践的过程无需花费任何额外的费用,因为 XS 缓存有免费的评估版可用。相关的下载链接如下所示。
您可以使用 WebSphere eXtreme Scale (WXS) 代替 OpenJPA 内的缓存来充分利用嵌入的、嵌入分区的远端缓存。
本文是两篇系列文章中的第一篇。本文将会讨论在没有应用服务器的情况下使用 OpenJPA 和 eXtreme Scale。本文的重点是 Plain Old Java Objects (POJO) 和 JDK。第 2 部分将会给出在有应用服务器的情况下的一个示例并尝试类似的测试。
您可以按如下步骤尝试 OpenJPA、IBM WebSphere eXtreme Scale、Informix 和 DB2 的安装、配置和测试:
- 进行如下的下载、安装和配置:
- OpenJPA
- WebSphere Extreme Scale Cache
- Informix Innovator C Edition 或 DB2 Express C
- 测试 OpenJPA,无缓存。
- 将配置修改为使用 WebSphere eXtreme Scale 缓存。
- 测试 OpenJPA,有缓存。
- 修改 OpenJPA 示例来充当一个简单的测试装具模块(test harness)。
- 修改 OpenJPA 配置来连接到 Informix 或 DB2。
- 分析结果。
现在就开始享受新发现的性能改进吧!
为了避免混淆,先说明如下:OpenJPA 是一个 Apache 项目。WebSphere eXtreme Scale、Informix 和 DB2 是 IBM 产品。Informix 和 DB2 有许可证免费的下载版本,而 WebSphere eXtreme Scale 则只有免费的试用版下载。试用期结束后,必须购买许可证才可继续使用 XS。问题解决了,让我们回到技术上来!
下载和安装并不太困难。您将需要先在 IBM 网站上注册。为进行本文所需的下载而获得一个 ID 是不需要费用的。所需链接如下:
如只是想尝试 OpenJPA 和 XS 缓存,则无需下载数据库。在进行性能测试时,若能看到用户、SQL、缓冲池命中率等,无疑更为有趣。这里的示例均来自 Informix 和 DB2。我们鼓励您自己挑选一个并开始尝试。选择后,就可以向前跳转来使用与 OpenJPA 捆绑的 Derby 数据库。
由于目前已经有很多资料讲述如何安装此软件,因此本文不再赘述。下载后,若想获得更多信息,可以查找有关安装向导和其他文档的链接。
完成全部下载后,Linux 系统上的目录列表应该类似于清单 1,也可以使用 md5sum
来确认目录列表如否如您所愿。
清单 1. Linux 系统上的下载目录列表
-rw-r--r-- 1 lurie lurie 29418160 2010-12-31 16:47 apache-openjpa-2.0.1-binary.zip -rw-r--r-- 1 lurie lurie 427579388 2010-12-31 17:35 db2exc_972_LNX_x86.tar.gz -rw-r--r-- 1 lurie lurie 69655311 2010-12-31 17:08 extremescaletrial710.zip -rw-r--r-- 1 lurie lurie 356157440 2010-12-31 17:34 iif.11.70.UC1IE.Linux-RHEL5.tar |
将这些文件解压缩到分级目录。表 1 列出了启动每个安装所需的软件和安装命令。
表 1. 安装快速入门, .sh 命令是针对 UNIX/Linux 的,.bat 是针对 Windows
| 软件 | 安装或执行命令 |
|---|---|
| OpenJPA | apache-openjpa-2.0.1/examples/hellojpa/ant |
| WebSphere eXtreme Scale | ObjectGrid/gettingstarted/env.sh, runcat.sh, runcontainer.sh c1, runclient.sh i hello world |
| Informix Dynamic Server | sudo informix/ids_install |
| DB2 | expc/db2setup |
遵循针对 Informix 和 DB2 的默认设置。让脚本为您创建一个示例数据库实例。DB2 的图形入口点如图 1 所示。
图 1. DB2 的安装入口点
运行 OpenJPA 提供的 ant
脚本的结果如清单 2 所示。虽然缓存尚未引入,但创建一个表也只花了 115 毫秒。基于持久化一个 Java 对象,插入一行花了 12 毫秒。而将这个对象读回则花了 1 毫秒。也许,说这些数据令人兴奋未免有些夸大其辞,但随着我们向前进展,事情会逐渐有趣起来。
清单 2. 来自基线测试的 OpenJPA 输出
lurie@merlin:/work/dwOpenJPA/work/openjpa/apache-openjpa-2.0.1/examples/hellojpa$ ant
Buildfile: build.xml
pre-compile:
compile:
[javac] Compiling 2 source files
run:
[java] 4232 hellojpa TRACE [main] openjpa.jdbc.SQL - t 8204368, conn 15666395
executing stmnt 22424679 CREATE TABLE Message (id BIGINT NOT NULL, created TIMESTAMP,
message VARCHAR(255), PRIMARY KEY (id))
[java] 4347 hellojpa TRACE [main] openjpa.jdbc.SQL - t 8204368, conn 15666395
[115 ms] spent
[java] 4683 hellojpa TRACE [main] openjpa.jdbc.SQL - t 8204368, conn 15975876
executing prepstmnt 29412736 INSERT INTO Message
(id, created, message) VALUES (?, ?, ?) [params=?, ?, ?]
[java] 4695 hellojpa TRACE [main] openjpa.jdbc.SQL - t 8204368, conn 15975876
[12 ms] spent
[java] 4969 hellojpa TRACE [main] openjpa.jdbc.SQL - t 8204368, conn 20336357
executing prepstmnt 32685187 SELECT t0.id, t0.created, t0.message FROM Message t0
[java] 4970 hellojpa TRACE [main] openjpa.jdbc.SQL - t 8204368, conn 20336357
[1 ms] spent
[java] Hello Persistence! (created on: Mon Jan 03 13:18:48 EST 2011)
BUILD SUCCESSFUL
Total time: 10 seconds
|
将配置修改为使用 WebSphere eXtreme Scale 缓存
下一步是在不对 Java 代码进行更改的情况下激活 WebSphere eXtreme Scale 缓存!做法是:修改
OpenJPA persistence.xml 文件,以及将 XS jar 添加到 build.xml 的 classpath 内,如清单 3 和清单 4 所示。请注意 hellojpa 构建文件使用的是父目录内的构建文件。
在使用 eXtreme Scale 缓存时,请确保使用 IBM JDK。
清单 3. 对 apache-openjpa-2.0.1/examples/META-INF/persistence.xml 的修改
<property name="openjpa.ConnectionPassword"
value="secret"/>
<property name="openjpa.DataCache"
value="com.ibm.websphere.objectgrid.openjpa.ObjectGridDataCache(
ObjectGridName=BasicTestObjectGrid,ObjectGridType=EMBEDDED,
maxNumberOfReplicas=4)"/>
<property name="openjpa.QueryCache"
value="com.ibm.websphere.objectgrid.openjpa.ObjectGridQueryCache()"/>
<property name="openjpa.RemoteCommitProvider" value="sjvm"/>
<properties>
<persistence-unit>
|
清单 4. 对 apache-openjpa-2.0.1/examples/build.xml 的修改
<fileset dir="${root}">
<include name="openjpa-all-*.jar"/>
<include name="lib/derby*.jar"/>
<fileset>
<!-- add path to the eXtreme Scale jar file -->
<pathelement path="xs"/>
<fileset dir="/home/lurie/tmp/xs71/ObjectGrid/lib">
<include name="objectgrid.jar"/>
<fileset>
<!-- end of mods to find eXtreme Scale jar file -->
</path>
|
现在缓存已启用,对 Java 程序则没有进行任何更改,缓存就已经准备就绪了。
好了!现在是时候运行示例了。在这之前,确保将路径配置为使用 IBM JVM,然后通过在命令行键入 ant 重新运行这个示例,如清单 5 所示。
清单 5. 在启用了 eXtreme Scale 缓存的情况下运行 OpenJPA 示例程序
/work/dwOpenJPA/work/openjpa/apache-openjpa-2.0.1/examples/hellojpa$ ant
[java] ReplicatedPar I CWOBJ1511I: BasicTestObjectGrid:IBM_SYSTEM_ENTITYMANAGER_MAPSET:0
(primary) is open for business.
[java] ReplicatedPar I CWOBJ1511I: BasicTestObjectGrid:MAPSET_BasicTestObjectGrid:0
(primary) is open for business.
[java] ObjectGridRes I CWOBJ3134I: The ObjectGrid type is embedded and the default
maximum number of replicas is 47. The maximum number of replicas must be
greater than or equal to the number of JVMs in the system.
[java] hellojpa TRACE [P=324170:O=0:CT] openjpa.jdbc.SQL - <t 1720215176,
conn 362616221> executing prepstmnt 652224224 INSERT INTO Message
(id, created, message) VALUES (?, ?, ?) [params=?, ?, ?]
[java] hellojpa TRACE [P=324170:O=0:CT] openjpa.jdbc.SQL - <t 1720215176,
conn 362616221> [212 ms] spent
... lines deleted ...
[java] hellojpa TRACE [P=324170:O=0:CT] openjpa.jdbc.SQL - <t 1720215176,
conn 696330625> executing prepstmnt 856306442 SELECT t0.id, t0.created,
t0.message FROM Message t0
[java] hellojpa TRACE [P=324170:O=0:CT] openjpa.jdbc.SQL - <t 1720215176,
conn 696330625> [1 ms] spent
|
其结果与第一种情况无异。为什么?如果数据库内只有一行,那么有无缓存的意义不大。如果这里所展示的对您而言太明显不过,那么就对不起了。为了让事情更为有趣,我们需要一个更好的包含了几千行代码的测试。
您可能厌烦了所有的 SQL TRACE 消息在您屏幕上滚动。为了切换到只显示警告消息,可以对 build.xml
文件进行编辑,使其类似如下所示:
value="DefaultLevel=WARN,SQL=WARN"。
修改 OpenJPA 示例充当一个简单的测试装具模块:向 Main.java 添加循环
对于产品应用程序,研究预期的工作负载并开发一个最接近现实的测试装具模块十分关键。用大量的仿真历史数据,比如一年的数据,对事务系统进行足尺测试是一个基本常识,除非您想要产品系统出现紧急情况。
在本例中,您可以简单创建一个循环来插入很多对象,然后再将这些对象读回。虽然它将展示缓存的有效性,但是只有在产品环境中运行
helloJPA 它才能代表一个合适的测试装具模块。
清单 6 显示了对 Main.java 程序的修改,以及如何插入 100 行。这不是什么大的挑战。由于此次测试关乎的是性能,所以您将需要在下一节内将 Informix 添加到配置内。Derby 对于开发而言很好,但如果就起重而言,Informix 无疑是更好的选择。样例文件还包含了在 DB2 上运行所需的配置。在用 Informix 进行测试时,此循环会插入更多行,这也让它变得更为有趣。
清单 6. 修改 openjpa Main.java 加入 100 行
EntityManager em = factory.createEntityManager();
// *** loop here to put a bunch of rows in the database
for ( int i=0; i<100;i++)
{
// *** don't forget to put a closing } below
// Begin a new local transaction so that we can persist a new entity
em.getTransaction().begin();
// Create and persist a new Message entbity
em.persist(new Message("Hello Persistence!"));
// Commit the transaction, which will cause the entity to
// be stored in the database
em.getTransaction().commit();
// *** end of loop
}
|
如果您只需读取这些条目一次,那么缓存实际上帮助不大。如清单 7 所示修改
Main.java 来读取并报告您已经持久到磁盘的两个传递的时机。
清单 7. Main.java 进行了被持久化对象的两次读取
// Create a fresh, new EntityManager
EntityManager em2 = factory.createEntityManager();
// **** set up a timer of how long the queries take
long starttm = System.currentTimeMillis();
// Perform a simple query for all the Message entities
Query q = em2.createQuery("select m from Message m");
// Go through each of the entities and print out each of their
// messages, as well as the date on which it was created
for (Message m : (List<Message> q.getResultList()) {
// *** better comment this out or 20,000 prints are coming back!
// System.out.println(m.getMessage()
// + " (created on: " + m.getCreated() + ")");
}
// *** report on the first run
long end1sttm = System.currentTimeMillis();
System.out.println("\n\nfirst run took: " + (end1sttm-starttm) +
" millisec\n\n\n");
// **** second run should be in local cache
// Perform a simple query for all the Message entities
Query q2 = em2.createQuery("select m from Message m");
// Go through each of the entities and print out each of their
// messages, as well as the date on which it was created
for (Message m : (List<Message> q2.getResultList()) {
//System.out.println(m.getMessage()
//+ " (created on: " + m.getCreated() + ")");
}
long end2ndtm = System.currentTimeMillis();
System.out.println("\n\nsecond run, from cache took: "
+ (end2ndtm-end1sttm) + " millisec\n\n\n");
// Again, it is always good to clean up after ourselves
em2.close();
|
结果如清单 8 所示,显示了使用 WebSphere eXtreme Scale Cache 后的显著加速。并且请记住,其中完全没有涉及任何的应用程序代码更改!我知道因添加循环来生成较重的工作负载,您还是会认同我所说的没有进行代码更改 。
清单 8. 测试运行的输出:联合使用 WebSphere eXtreme Scale 与 Derby 数据库而获得的明显加速
[java] [1/26/11 11:00:11:776 EST] 3a883a88 SystemOut O
[java]
[java] first run took: 3761 millisec
[java]
[java]
[java]
[java] [1/26/11 11:00:11:865 EST] 3a883a88 SystemOut O
[java]
[java] second run, from cache took: 89 millisec
[java]
[java]
|
性能的改善超过 40 倍:3761 毫秒对 89 毫秒。当然,这取决于硬件,所以您的具体数据可能会与此不同。 还有其他几个环境因素,也会影响性能。比如,如果您在调整/调换任何相关的性能,那么数据就没有讨论的意义了。
修改 OpenJPA 配置连接到 Informix 或 DB2
一个更为实际的测试是对一个具有行业强度的数据库使用 OpenJPA。好的消息是把数据库从 Derby 更改为 Informix
只需对
build.xml 文件进行一些简单的修改,如清单 9 所示。不仅数据库的指标更改了,并且还要求有到 jdbc jar 的路径。
清单 9. 修改 build.xml 以使用 Informix Dynamic Server
build.xml
<project default="usagewarning">>
<property name="parent" value="${basedir}/.."/>
<property name="root" value="${parent}/.."/>
<!-- database connection properties
<property name="dbdriver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="dburl"
value="jdbc:derby:${basedir}/${example}-database;create=true"/>
<property name="dbuser" value=""/>
<property name="dbpass" value=""/>
-->
<!-- database connection properties -->
<!-- informix instead of derby -->
<property name="dbdriver" value="com.informix.jdbc.IfxDriver"/>
<property name="dburl"
value="jdbc:informix-sqli://merlin:54321/idsopenjpa:informixserver=ids115"/>
<property name="dbuser" value="informix"/>
<property name="dbpass" value="idsr0cks"/>
<target name="usagewarning">
PATH CHANGES
<path id="classpath"
description="The classpath to use for compiling and running">
<pathelement path="${parent}"/>
<fileset dir="${root}">
<include name="**/*.jar"/>
</fileset>
<pathelement path="xs"/>
<fileset dir="/home/lurie/tmp/xs71/ObjectGrid/lib">
<include name="objectgrid.jar"/>
</fileset>
<pathelement path="ifx"/>
<fileset dir="/opt/IBM/informix/jdbc/lib">
<include name="ifxjdbc.jar"/>
</fileset>
</path>
Informix Configuration
Don't create any tables, just a database. It seems almost too easy.
informix@merlin:~$ dbaccess - -
> create database idsopenjpa with buffered log;
Database created.
|
它真的变快了么?如果没有变快,阅读本文岂不是浪费时间!如清单 10 所示,对 Main.java 程序进行修改以插入 10,000 行。Informix 在 1 秒内就能制作出 10,000 行,因为它具有高级的缓冲池管理和行业强度的架构。此外,通过将数据保存在地址空间与 Java 应用程序相同的缓存内,也会显著提高性能。对于任何一个数据库而言,能够突破 49 毫秒的缓存存取底线同时又能完成 TCP/IP 的双向遍历都是一个极大的挑战。
清单 10. 测试运行的输出:联合使用 WebSphere eXtreme Scale 与 Informix 数据库而获得的明显加速
[java] [1/26/11 17:28:38:751 EST] 72887288 SystemOut O
[java]
[java] first run took: 1096 millisec rows processed= 10000
[java]
[java]
[java]
[java] [1/26/11 17:28:38:800 EST] 72887288 SystemOut O
[java]
[java] second run, from cache took: 49 millisec
[java]
|
如果您对数据库层面发生的事情感兴趣,那么可以参看清单 11 所示的这个模式。
清单 11. Informix 数据库模式
create table "informix".message
(
id decimal(32,0) not null ,
created datetime year to fraction(3),
message varchar(255),
primary key (id)
);
|
本文通过对 OpenJPA、 WebSphere eXtreme Scale 及 Java 缓存与 Informix Dynamic Server 数据库结合使用的快速介绍让您对它们有了基本的了解。所提供的样例文件包括上述的所有代码,当然也包括了用 DB2 做相应实现的内容。
请您自己尽情尝试吧!
如果您想要了解有关此主题的更多信息,那么千万不要错过 Informix International Users Group(参见 参考资料 获得更多细节),在那里 Marty 继续为我们阐述这个主题。
| 描述 | 名字 | 大小 | 下载方法 |
|---|---|---|---|
| 本文的示例文件 | sampleFiles.tar | 50B | HTTP |
学习
- 使用 RSS 提要 请求收到本系列的下一篇文章发表时的通知。(更多地了解有关
developerWorks 内容的 RSS 提要。))
- 启用 使用 XML-RPC 为 C++ 应用程序启用 Web 服务(developerWorks,2006 年 6 月)是一个有关将 C++ 方法作为服务公开的逐步指导。
- 访问 developerWorks 上的 Informix 专题 获得增进您的 Informix 技能所需的资源。
- 访问 Informix International Users
Group,在那里,可以找到 Marty 在 IIUG Informix
Conference 上做的有关此主题的演讲。
- 随时关注 developerWorks 技术活动 和 网络广播,包括各种 IBM 产品和 IT 行业主题。
- 在 developerWorks 中国网站 Information Management 专区,更多地了解信息管理,获得技术文档、how-to
文章、教程、下载、产品信息等。
- 参阅 Marty Lurie
名为 急性者的 WebSphere 优化:如何通过 20% 的工作获得 80% 的性能改善 的文章,其中包含了与性能调优相关的环境方面的讨论。
- 参阅 Marty Lurie
名为 Real Time Data Acquisition 的文章,了解使用 Java 和 Linux 将您的测试连接到 Informix 或 DB2 来捕获实时的数据。
- 参阅 Marty Lurie
名为 在 Linux 上模拟大规模并行数据库处理!的文章。
- 参阅 Marty Lurie
名为 联邦 - 数据库互操作性(第 1 部分) 和 联邦 - 数据库互操作性,继续大胆尝试(第 2 部分) 的文章。
- 参阅 Marty Lurie
名为 Tunneling secure traffic via ssh 的文章。
- 参阅 Marty Lurie
名为 Web click stream analysis on Linux 的文章。
- 参阅 Marty Lurie
名为 Informix administration 的文章。
- 参阅 Marty Lurie
名为 用 DB2、PHP 和 Linux 实现 Web 投票 的文章。
获得产品和技术
- 用 IBM 产品评估试用版软件 构建您的下一个开发项目,这些软件可直接从
developerWorks 下载。
- 下载 Informix Innovator-C 的免费版本,这是一个面向小型工作负载而设计的 Informix 版本。
- 下载
试用版: WebSphere eXtreme Scale 的评估版。
- 下载 IBM 软件下载:IBM DB2 Express-C 9.5,这是 DB2 for Linux, Windows, and Mac 的免费版本,它简单易用并且为构建和部署应用程序奠定了坚实的基础。
讨论
- 参与论坛讨论。
- 参与 developerWorks 博客 并加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。