IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Linux  >

基于 iSeries 和 DB2 UDB for iSeries 的 Linux 三层应用程序最佳实践、设计和性能优化

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

Brent Baude (baude@us.ibm.com), Linux on POWER 技术顾问, IBM 
Jarek Miszczyk (jarek@us.ibm.com), 高级软件工程师, IBM 

2004 年 12 月 27 日

自 Linux 在 IBM eServer iSeries 服务器上运行开始,计算环境和传统的 iSeries 工作负载就发生了变化。人们称 Linux 和 OS/400 是最稳定的操作环境。但实际上在 iSeries 硬件上运行的 Linux 与 OS/400 本身的结合创造了这个非凡的环境。每个部分都将自己的强大能力引入到这个综合体中,为解决方案开发人员和终端用户等提供了更多的可能性。iSeries 硬件及其分区能力不仅使用户能够利用整个 iSeries 服务器,而且创造了把多台服务器统一成一个的伟大神话。OS/400 在稳定性、安全性和业务线应用程序方面享有毫无瑕疵的美誉,DB2 UDB for iSeries 则是其基础。而 Linux 则在这些传统的作业方式中引入了开放源码运动,让用户增加原来的 iSeries 服务器中没有的功能,开发自己的解决方案。因此,Linux on iSeries 实现在 2001 年度的 Linux World 中赢得“最佳展示奖”就毫不奇怪了。

简介

随着 Linux on iSeries 环境的成熟,它的解决方案套件也成熟起来。公司和解决方案开发人员一样,不仅面临着在 Linux 分区中巩固其基础设施应用程序的压力,也看到了这样做的好处。但是在如何利用 iSeries 硬件、OS/400、Linux 以及两层或三层应用程序的强大功能方面,目前存在着不同的观点。一种典型的应用程序蓝图是,不同的客户机和 Linux 分区的一个应用服务器通信,后者再与 DB2 UDB for iSeries 交互。无论是在新的 iSeries 服务器中,还是在传统的 iSeries 服务器中,这种类型的应用程序都在发挥着越来越大的作用。但是和任何三层应用程序部署一样,如果开发人员希望得到最好的性能,就必须遵循业界认可的一些最佳实践。本文的目的就是介绍在使用 DB2 UDB 的 Linux on iSeries 分区上部署三层数据库驱动应用程序的最佳实践。虽然本文主要讨论三层部署,但很多技术和考量也适用于使用 Linux 和 DB2 UDB for iSeries 的两层部署。本文首先描述这类应用程序的一个示例框架,介绍不同的组件。然后进一步详细讨论应用程序中的各个组件,阐述每个组件需要考虑的问题。





回页首


三层应用程序的典型组成

图 1 描述了 iSeries 服务器上使用 Linux 的三层应用程序的示例框架。在这里,有多个“终端用户”访问 Linux 分区上运行的解决方案开发人员应用程序。这些终端用户通常是输入数据或者检索数据。终端用户的工作站可以是 Linux 或 Microsoft Windows,所用的应用程序就是所谓的应用程序客户机版本。客户机直接使用 TCP/IP 通信与 iSeries 服务器上的 Linux 服务器应用程序交互。


图 1. Linux、DB2 UDB、OS/400 三层应用程序的布局

然后,Linux 分区中的服务器应用程序使用虚拟 LAN 和 DB2 UDB for iSeries 通信。UDB for iSeries 和 Linux 分区之间的通信部分使用数据库连接程序,如 ODBC 或 JDBC 驱动程序。如图 1 所示,即使典型的三层应用程序框架也非常复杂,各个部分之间必须有系统地工作,否则很容易出现性能问题。这些组件中如果存在任何形式的低效,都可能造成性能瓶颈。与常见的情况一样,应用程序设计和应用程序实现之间的转换常常是问题的根源。本文使用上面的三层应用程序示例框架,进一步分解和讨论其中的每个组件,主要是常见的实现错误,某些情况下还涉及到性能的测量和优化。

Linux on POWER 运行时

iSeries 平台基于不同的 PowerPC 处理器,这取决于所用的 iSeries 模型。因此,如果开发人员希望在 iSeries 服务器上运行 Linux,就应该针对 PowerPC 编译 Linux 核心和应用程序。在 iSeries 服务器上和 pSeries 一样,开发人员都可以运行 32 位和 64 位应用程序。但与其他 64 位平台不同,在 PowerPC 64 位处理器上运行 32 位应用程序没有性能损失。典型的 iSeries 服务器 Linux 版本都提供 64 位的核心,而应用程序多数都是 32 位的。确定应用程序要使用 32 位还是 64 位,要根据应用程序是否能从 64 位代码中获益来判断。运行在该环境中的大量应用程序都是 32 位的。比如,随发行包提供的应用程序基本上都是 32 位的,如 XFree 组件和网络守护程序。

应用服务器

在这三层应用程序例子中,应用服务器在 iSeries 服务器上的 Linux 分区中运行。它主要作为一个仲裁者,处理不同数据源如客户机和数据库本身之间传递的数据。在简单的事务中,应用程序从客户机接收初始请求,然后通过向数据库发送信息或者从中检索信息来处理请求。这些请求完成后,应用程序服务器通常处理数据响应并返回给客户机。。

ODBC 驱动程序

如前所述,应用程序可以使用 ODBC 或者 JDBC 驱动程序连接到后端的 DB2 UDB for iSeries 数据库。本文主要讨论 ODBC 数据库连接。多数 ODBC 技巧和技术也适用于 IBM Toolbox for Java JDBC 。从 Linux 分区中访问 DB2 for iSeries 的 JDBC 特殊问题,MC Press 在线文章“ Using JDBC in an iSeries Linux Partition”(http://www.mcpressonline.com/mc/.6ae8441d)中有详细讨论。

iSeries ODBC Driver for Linux 是一种 ODBC 驱动程序,允许开发人员从 Linux 客户机上访问 iSeries 数据库。iSeries ODBC Driver for Linux 以 iSeries Access for Windows 中的 ODBC 驱动程序为基础。与 iSeries Access 驱动程序类似,Linux ODBC 驱动程序使用 iSeries 数据库 Host Servers 作为访问服务器的访问点。驱动程序通过套接字连接和服务器通信。

Red Hat 和 SUSE Linux 8 都采用 RPM 格式作为发行包的一部分提供 ODBC。开发人员也可以从 IBM iSeries ODBC Driver for Linux 网站(http://www-1.ibm.com/servers/eserver/iseries/linux/odbc/)下载最新、最好的 ODBC 驱动程序。这个网站还提供了安装说明,以及使用 ODBC、PHP 和 Apache web 服务器访问 DB2 UDB for iSeries 数据的例子。

虚拟以太网

任何逻辑分区都可以使用虚拟以太网建立多条分区间的高速连接。发表本文的时候,开发人员可以在一台 iSeries 服务器上配置多达 16 格不同的本地虚拟网。虚拟以太网基本上能够提高与 1 Gb 的以太网适配器相当的能力。虚拟以太网是硬件实现,但分区间通信使用普通的 TCP/IP。

在 Linux 中使用虚拟以太网不需要特殊的软件。驱动程序模块已经包含在 Linux 发行包中。与 Linux on iSeries 中的所有虚拟设备一样,Linux 将虚拟以太网视作普通的物理设备。使用虚拟以太网模块(veth)时将显示下面的消息:

veth.c: Initializing veth module, fabric mgr (address=c000000002f38000) 
veth.c: v1.07 07/01/2003 Kyle Lucke, klucke@us.ibm.com 
veth.c: Found an ethernet device eth0 (veth=0) (addr=c00000002e9e3400)

为虚拟以太网设备配置 TCP/IP 与配置其他物理网卡一样。如果虚拟以太网设备是第一个网络设备(eth0),那么开发人员可以手工添加网络接口:

localhost:~ # ifconfig eth0 192.168.1.2 netmask 255.255.255.0 \ 
broadcast 192.168.1.255

如果不使用手工方式,则 Red Hat 和 SUSE Linux 网络配置工具也能够识别虚拟以太网设备。

在 OS/400 中,虚拟以太网连接的配置方法和物理网卡一样。开发人员可以首先创建线路描述,然后再建立 TCP/IP 接口。为 OS/400 V5R2 配置虚拟以太网的更多细节,请访问 iSeries Information Center(http://publib.boulder.ibm.com/iseries/v5r2/ic2924/info/rzalm/rzalmvirtualkickoff.htm)。

DB2 for iSeries 数据库服务器任务

Linux ODBC 客户机向相应的 iSeries 服务器任务发送 SQL 请求。该服务器任务代表客户机运行该 SQL 请求。更准确地说,当 ODBC 客户机提交一个 SQL 语句时,会给该语句传递一个服务器任务,后者再调用 DB2 运行时执行该语句。查询结果经过重新格式化被发送给客户机。iSeries 数据库访问服务器任务被称为 QZDASOINIT,默认情况下是在 QUSRWRK 子系统中运行。图 2 说明了执行 ODBC 请求中所涉及到的典型软件组件。


图 2. ODBC 客户机如何访问 iSeries 服务器上的 DB2 UDB

DB2 UDB for iSeries 运行时

DB2 UDB for iSeries 是 DB2 家族的一个成员。DB2 UDB for iSeries 引擎集成到 OS/400 中。它使用并依赖操作系统提供锁定、安全、存档/备份、缓冲管理和事务服务等功能。操作系统反过来又依靠数据库引擎提供某些服务。DB2 SQL 运行时支持提交 SQL 语句执行可用的多种方法,本文后面将详细讨论。


图 3. DB2 UDB for iSeries SQL 运行时

静态 SQL

SQL 语句嵌入到宿主应用程序的源代码中。比如,用 C++ 编写的存储过程可以包含多个内嵌的 SQL 语句。这种情况下,在编译宿主应用程序本身之前,存储过程源代码必须经过 SQL 预编译器的处理。在这个过程中,内嵌的 SQL 语句被解析、验证和优化。处理完成后,每个语句都生成相应的访问计划。访问计划是一种控制结构,包含为实现 SQL 请求所必须执行的动作信息。一般而言,其中包括:

  • 优化程序为给定语句选择的访问方法(比如表扫描)。
  • 运行时所使用的相关表和索引的信息,以便确定当表或者索引变化时是否需要重建访问计划。
  • 任何可用的环境信息,如任务的代码页。

然后访问计划被永久保存在程序对象中,在程序执行时可以被重用。静态 SQL 是在 iSeries 服务器上处理 SQL 请求最有效的方式。

动态 SQL

动态 SQL 语句在 SQL 应用程序执行时解析、验证和优化。使用 SQL 语句 PREPARE 或者 EXECUTE IMMEDIATE,可以将 SQL 语句以字符串的形式传递给数据库管理程序。当启用 Extended Dynamic SQL 支持选项时,iSeries Access ODBC 驱动程序和 IBM Toolbox for Java JDBC 驱动程序就使用这种方法。更多信息请参阅本文“连接关键字”一节。

Extended Dynamic SQL

在 Extended Dynamic SQL 中,SQL 语句是动态的。但是,用于实现动态 SQL 语句的 SQL 包和静态 SQL 相似。SQL 语句被解析、验证和优化,得到的访问计划永久保存在 SQL 包中。iSeries Access ODBC 驱动程序可以利用 Extended Dynamic SQL 支持。

客户机工作站

在这个应用程序框架中,“客户机”指的是向应用服务器发起请求的组件。事实上,在典型的部署中,常常有很多客户机。本文所用的例子中,客户机可以是运行 Windows 或者 Linux 的桌面工作站。在客户机上,终端用户与应用服务器进行交互、录入数据、检索数据或者生成报表。客户机工作站常常运行一个专门的应用程序,负责与应用服务器进行交互。客户机工作站本身很少决定应用程序框架的性能,但是性能常常在客户机工作站上反映出来,最常见的是响应时间。常见的征兆是,当客户通过电话订货时,公司代表却说“请等一下,今天我的计算机很慢”或者“今天系统很慢”。这很可能是整个应用程序框架造成的,而不是销售代表的计算机出了问题。





回页首


最佳实践、设计和性能

本文前面几个小节将介绍组成典型三层应用程序的组件。每个组件都对整个框架的性能有影响。为了使这个框架正常、有效地运转,必须考虑每个组件的性能。下面分别介绍各个组件的设计和最佳实践。此外,一定要下载并应用最新的 OS/400 PIF,保证使用最新的服务器更新。对于 Linux,一定要从发行商那里获得最新的 RPM。

客户机和应用服务器通信

谈到客户机和服务器的通信,脑子里想到了很多问题,有些很明显,有些则不那么清楚。在讨论客户机和服务器通信时,作者将介绍 Linux on iSeries 特有的客户机/服务器通信问题,以及这类部署中我们遇到过的一些常见问题。

对于性能敏感的客户机/服务器通信,作者的建议之一是直接在 Linux 分区添加网络接口卡(NIC)。虽然对于分区间通信使用虚拟以太网的成本更低(请参阅前面的叙述),但是对应用服务器使用虚拟以太网将迫使开发人员在另一分区中使用网络地址翻译(NAT)或者 proxy-arp。NAT 和 proxy-arp 可以有效实现从分区到物理 LAN 的路由,但是对于性能敏感的应用程序,它会增加网络响应时间。对于直接插入的网络适配器,就不需要额外的路由,分区可以直接连接到物理 LAN。关于 Linux on iSeries 所支持的 NIC 清单,请参阅“ iSeries I/O adapters (IOAs) supported by Linux”(http://publib.boulder.ibm.com/iseries/v5r2/ic2924/info/rzalm/rzalmioa.htm

)。

Nagle 算法(根据其作者 John Nagle 命名)是一种 TCP 拥塞控制算法,目的是为了减少发送到网络上的小分组的数量。关于该算法的完整讨论,请访问 Internet Engineering Task Force 网站(www.ietf.org/rfc/rfc0896.txt?number=896)。虽然 Nagle 算法适用于很多环境,但经常发现它会影响在 LAN 上运行的客户机/服务器应用程序性能。Nagle 算法默认应用于每个套接字连接。所幸的是,通过将 TCP_NODELAY 选项的值设为 1 (可选),对套接字调用 setsockopt() 可以在特定的套接字上禁用该算法。将客户机和服务器套接字的 TCP_NODELAY 选项设置为可配置的应用程序级参数是可取的做法。对于主要在 LAN 上进行的通信,客户机和服务器套接字上的 TCP_NODELAY 默认值应该设为 1。

从关于 Nagle 算法的讨论可以得出,最好是尽可能将数据一次写入套接字,而不要在应用程序级对数据分段然后通过多次操作写入套接字。比方说,如果有 3000 个字节要发送到套接字,我们更希望在一次操作中将所有 3000 个字节都写入套接字,而不是每次写入 1000 字节分三次写入。如果有大量的数据写入套接字,那么 TCP/IP 可以更有效地把数据发送给接收方,这样做通常可以减少分组的数量,减少发送方和接收方的 CPU 占用。

应用服务器

既然运行在 Linux 中的应用服务器是应用程序设计的核心,那么其性能的好坏就至关重要。很多明显的问题,如适当的处理器能力和内存,在涉及到性能时都是需要优先考虑的问题。对前面描述的三层数据库应用程序,还需要考虑线程和进程管理。但关于如何在这些方面做到最好实际上依赖于应用程序本身及其使用。

很多在 Linux on Power 上运行的应用程序都是使用 GNU Compiler Collection (GCC) 编译的。GCC 包括 GNU C 编译器 gcc、GNU C++ 编译器 g++ 和 GNU Fortran77 编译器 g77。如果开发人员使用 GCC 编译 Linux on Power 应用程序的源代码,那么开发人员至少应该传递以下参数:

  • (-02) 一般的经验表明,对于 Linux on Power 应用程序,开发人员首先应该向 GCC 编译器传递 -02 标志。-02 标志可以提供足够的优化。
  • (-fpic 或 -fPIC) 对于 PowerPC 体系结构,开发人员应该传递一个 fpic 选项。如果共享库没有使用 -fpic 或 -fPIC 编译,那么开发人员就无法获得共享库的主要优点:库应该在进程间共享。它还不符合 ELF 符号覆盖规则,这个规则允许应用程序或者其他共享库提供函数代替共享库中的函数。结果造成更加动态的重定位,转变成更长的启动时间。如果开发人员使用 -fPIC 编译,会生成更多的代码来处理更大的全局偏移表(GOT),某些情况下,这样做是可取的。

如果从共享的处理器池中使用多个虚拟处理器,传递核心参数 spread_lpevents 可能使应用程序得到更好的性能。正确的语法是:spread_lpevents=n,其中“n”是池中的处理器个数。如果应用程序或者作业遇到很多的处理器中断,建议开发人员尝试一下该参数,然后测试看看是否有所改进。传递给核心的参数通过 OS/400 的网络服务器描述(NWSD)上的 IPL Parameters 字段增加。下面的 NWSD 中传递了根磁盘分区和 spread_lpevents:

ODBC 连接

除了 iSeries ODBC Driver for Linux 外,为了成功在 Linux 分区中运行 ODBC 应用程序,该分区中还需要其他两个组件:

  • unixODBC Driver Manager Version 2.0.11 或更高版本 —— unixODBC 是一个应用程序和库(被称作驱动程序管理器),它知道可用的驱动程序,允许定义新的数据源、管理已定义数据源的连接。所幸的是,Linux on iSeries 发行包中已经包含了预先编译好的 unixODBC Driver Manager PowerPC 版本。使用下面的命令可以检查当前安装在 Linux 分区中的版本:
    # rpm -qa | grep unixODBC
    

  • libodbc.so 共享库 —— ODBC 应用程序链接时需要这个库。一定要保证 /usr/lib 目录中有适当的链接。有时候软链接可能会丢失,编译过程的链接阶段会失败。这个问题很容易解决,只需手工创建一个符号链接,指向和 unixODBC 驱动程序管理器一起安装的共享库即可,比如:
    # ln -s /usr/lib/libodbc.so.1.0.0 /usr/lib/libodbc.so
    

虽然系统中可能已经存在 iSeries ODBC Driver for Linuxh 的 RPM (Red Hat Package Manager) 镜像,但作者强烈建议从前面所说的 URL 下载最新的驱动程序版本。服务器上按照的版本至少为 iSeriesODBC-5.1.0-0.16.ppc.rpm 或更高版本,这个版本修正了几个重要的内存问题,可以显著降低驱动程序的内存占用。

驱动程序可以使用 RPM 命令安装,如:

# rpm –ivh iSeriesODBC-5.1.0-0.16.ppc.rpm

驱动程序安装过程向驱动程序管理器注册 iSeries ODBC 驱动程序,在 odbcinst.ini 配置文件中增加驱动程序信息。该文件位于 /etc/unixODBC 目录中(以前的驱动程序管理器版本中为 /etc)。下面是 odbcinst.ini 文件中可能包含的内容:

[iSeries Access ODBC Driver]    
Description            = iSeries Access for Linux ODBC Driver 
Driver                 = /opt/ibm/iSeriesODBC/lib/libcwbodbc.so 
Setup                  = /opt/ibm/iSeriesODBC/lib/libcwbodbc.so 
Threading              = 2

配置过程的下一步是为 iSeries 数据库创建数据源名(DSN)。可以使用图形化工具 ODBCConfig 或者编辑 odbc.ini 配置文件来完成这项操作。

DSN 记录有两种类型:系统 DSN 和用户 DSN。系统 DSN 通常从根创建,位于 /etc/unixODBC 目录中。该系统上的任何用户都可以使用系统 DSN。用户仅对特定的用户有效,不能与系统的其他用户共享。用户 DSN 的配置文件名为 .odbc.ini,位于用户的主目录中,如 /home/jarek/.odbc.ini

下面是添加到 odbc.ini 文件中的一个系统 DSN:

[os400] Description = iSeries os400 
Driver = iSeries Access 
ODBC Driver System = os400

os400 是目标 iSeries 服务器的主机名。





回页首


这一节介绍 DB2 UDB for iSeries 上高效 ODBC 编程的几个主要问题。

iSeries ODBC 驱动程序支持一些连接关键字,可用于控制连接属性,改进应用程序性能。连接关键字的完整列表可以从 iSeries Information Center (http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm)找到。

指定连接属性有几种方法,比如修改 odbc.ini 文件中的 DSN 记录。图 4 是一个系统 DSN 的例子。

[os400] 
Description = iSeries os400 
Driver = iSeries Access ODBC Driver 
System = os400 
CommitMode = 2 
ExtendedDynamic = 1


图 4. 系统 DSN 记录的例子

此外,还可以在应用程序的连接字符串中指定连接属性关键字,图 5 中的代码片段说明了这种方法。


图 5. 在连接字符串中指定连接属性关键字

相关的关键字说明如下:

CommitMode
指定默认的事务隔离级别,这里设为 Read Uncommitted (*CHG)。
ExtendedDynamic
指定是否使用扩展动态包支持,1 表示启用该包,这也是 iSeries ODBC 驱动程序的默认值。
DefaultPkgLibrary
指定 SQL 包的库。注意,DefaultPkgLibrary 关键字不是必需的。如果没有指定 DefaultPkgLibrary,则这个包将存储在 QGPL 库中。
DefaultPackage
指定扩展动态包如何运作。DefaultPackage 关键字不是必需的,如果没有指定,则使用默认属性。

SQL 包是 SQL 语句的服务器端资料库。这个包拥有执行 SQL 语句所需要的内部结构(如解析树和访问计划)。因为 SQL 包是共享资源,所以准备该语句时建立的所有信息可以被这个包的所有用户共享。这样可以节约处理时间,特别是在很多用户使用相同或类似语句的环境中。因为 SQL 包是持久性的,所以这些信息也可以跨任务起始/终止以及跨 IPL 来保存。事实上,SQL 包还可以在其他系统上保存和恢复。通常不需要删除 SQL 包,但有时候仍然需要删除它,特别是当数据库设计发生重大变化时。可以使用 WRKOBJ 命令定位和删除 SQL 包。下面的命令查找名为 testodbc 的 ODBC 数据库应用程序的 SQL 包:

WRKOBJ OBJ(JAREK/*ALL) OBJTYPE(*SQLPKG)

实际的包名为 TESTODBCVBA,由服务器生成。SQL 包按照客户机应用程序的名字命名,后面的三个字母表示包的配置属性。

关于 iSeries SQL 包支持的更多信息,请参阅 DB2 UDB for iSeries FAQ section of the DB2 UDB for iSeries: Improving Performance with SQL Packages(http://www-1.ibm.com/servers/eserver/iseries/db2/sqlperffaq.htm)。





回页首


连接池

某些应用程序的结构需要频繁地建立和断开 ODBC 连接。这类应用程序在访问 DB2 UDB for iSeries 时的性能不佳。如果需要重新启动服务器任务,连接到 QZDASOINIT 服务器任务是一个相当昂贵的过程(参阅“数据库服务器任务”一节)。解决这一问题的方法是使用连接池。unixODBC 驱动程序管理器提供了简单的连接池机制,对应用程序访问 iSeries 数据库需要的连接数有潜在的限制。这完全依赖于 Linux 分区中运行的应用程序进程是否允许被多个客户机共享或重用。unixODBC 连接池实现仅在进程内有效。换句话说,如果调用进程和建立该连接的进程是同一个,连接就可以重用。只要应用程序从有限的几个永久进程中创建和关闭连接,连接池就可以改善性能。设置连接池非常简单,只要像图 6 那样编辑 odbcinst.ini 即可。


图 6. 编辑 odbcinst.ini 设置连接池

设置连接池最重要的两点是 Pooling = Yes 和 CPTimout。您可以试验一下后一个值。上面的例子中该值被设为 10 分钟。上述设置对于多次开启和关闭连接的测试程序工作得很好。在程序执行中,iSeries 服务器上只有一个 QZDASOINIT 任务,因为 SQLDisconnect 请求被驱动程序管理器拦截了,连接实际上没有关闭。

前面提到,只有在应用服务器管理从连接池中获得数据库连接的永久性进程(或线程)池时,这项技术才能有效地工作。但是有些应用程序并没有使用进程/线程池机制,而是每当客户机连接到应用程序服务器都创建新的进程。这类应用程序就无法使用 ODBC 管理器所提供的简单连接池的好处。这种情况下,为了改善性能,本文作者强烈建议应用服务器实现自己的数据库连接池机制,将已有的放在池中的数据库连接分配给新的 Linux 进程或线程。

虚拟 LAN

对于分区间的通信,开发人员应慎重考虑虚拟以太局域网。除了经济和易用性的因素外,虚拟以太局域网能够以接近 1 吉比特的速度运行。根据 2003 年 9 月召开的 V5R2 Performance Capabilities Reference,在低端的 iSeries 模型中,虚拟 Ethernet LAN 的性能保守估计可达到每秒 200-400 兆位、 1100-9500 个连接。每秒钟连接个数的变化是由于测量过程中不同的载荷造成的。Performance Capabilities Reference 可以从 IBM Performance Managemetn Resource Library 找到(http://www-1.ibm.com/servers/eserver/iseries/perfmgmt/resource.htm,PDF 格式)。在该指南的 Linux 一章,关于 Linux on POWERspecific 和 iSeries 服务器的性能有精彩的论述,还提供了改善性能的技巧列表。

但是在稍微复杂的分区环境中,还需要考虑其他因素。如果服务器中有多个分区共享一个虚拟以太局域网,那么还要考虑将 Linux 应用程序到 DB2 的通信隔离在单独的虚拟以太局域网中。从安全和性能的角度来看,这样做都有好处。图 7 给出了一个例子。左侧的服务器有多个分区,而且都在同一个虚拟以太局域网上。很可能形成的通信量过大而降低本文所述这类对网络敏感的应用程序的性能。在这种环境中,为应用服务器和 DB2 之间的通信建立第二个虚拟 Ethernet LAN 是一个不错的办法。


图 7. 隔离虚拟 Ethernet LAN 上的网络通信可以改善性能,降低网络风险

要配置虚拟 LAN,比如图 7 右侧的 iSeries 服务器,可以打开 Service Tools Server (SST) 并配置虚拟 Ethernet,使 LINUX1 运行应用程序服务服务器,DB2 UDB 在 PRIMARY 分区上运行。下面是隔离虚拟 Ethernet LAN 的示例设置:

此外,如果虚拟 Ethernet LAN 需要很高的网络流量,开发人员还要保证主分区或者宿主分区有足够的 CPU 和主存(RAM)来处理 CLAN 通信。如果宿主分区处理能力有限,可能要启用交换或者类似的机制,从而损害应用程序的性能。如果宿主分区没有足够的资源,在同时执行数据库操作,影响会更大。对于基于 Linux on iSeries 和 DB2 UDB for iSeries 的三层应用程序,最佳实践、设计和性能优化所需要的合理资源是多少,这依赖于应用程序、需要什么样的性能和运行的 iSeries 模型。如果进行应用程序测试和性能测试/度量,就可以确定需要的资源数量(请参阅本文“应用程序性能测量”一节)。

数据库服务器任务

到目前为止,读者已经了解了称为 QZDASOINIT 的 iSeries 数据库服务器任务,它们在 QUSRWRK 子系统中运行。现在我们来分析一些简单的 OS/400 性能优化技巧,这些技巧可以改进数据库服务器任务的性能。如果需要进一步了解系统性能优化措施,请与当地的 IBM 支持部门联系。应该首先进行以下检查:

  • QUSRWRK 子系统中的预启动任务数。

    要保证有足够的数据库服务器任务来满足客户机请求。否则,服务器就需要启动新的 QZDASOINIT 任务实例,从而不必要的消耗更多的系统资源并延长建立连接的时间。查看 QZDASOINIT 预启动任务的当前设置,可以使用 DSPSBSD SBSD(QUSRWRK) 命令并在 Prestart job 中选择 Option 10,然后对 QZDASOINIT 程序选择 Option 5 以显示细节。可以使用 CHGPJE SBSD(QUSRWRK) PGM(QSYS/QZDASOINIT) 命令改变参数。比如:

    • 初始任务数 —— 预启动任务第一次启动时最初启动的任务数。这个值默认为 1,对于多数三层应用程序而言,这个值太小了,开发人员应该将其设为 Linux 应用程序在给定时间需要的活动数据库连接数。比方说,如果预计有 100 个用户,平均需要两个数据库连接,那么该参数就应该设为 200。
    • 附加的任务数 —— 如果可用的预启动任务数低于 Threshold 参数,那么应该启动的附加预启动任务数。
    • 最大任务数 —— 同时活动的最大预启动任务数。

  • OS/400 分区中的磁盘臂个数。

    检查系统是否受 I/O 能力的制约。一般情况下,磁盘单元越多越好。服务器至少要有 4 个磁盘臂。使用 WRKDSKSTS 命令检查磁盘配置,检查磁盘利用率(% 忙)是否低于建议的 30%。还要保证使用的磁盘空间低于容量的 70%。

  • CPU 利用率。

    检查系统性能是否受到 CPU 的制约。使用 WRKSYSSTS 命令检查 CPU 利用率,应该低于 90%。

  • 内存池的大小和 QZDASOINI 任务所在内存池的最大活动级别。

    根据系统配置,这个值可以是 BASE 或 QBATCH。可以使用 DSPSBSD SBSD(QUSRWRK) 命令并在 Pool 定义中选择 Option 2 来检查该项设置。然后使用 WRKSYSSTS 命令保证为这个内存池分配足够多的空间。为了优化性能,每个活动数据库服务器任务应该有 10 MB 内存。还要看看指导原则中包含有 I/O 错误、 Act->Wait 和 Act->Inel 转换。有关的更多信息,请参阅 iSeries Information Center 网站(http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/rzahx/rzahxtunebasic.htm)“ Basic Performance Tuning”一节。

  • 为 QZDASOINIT 任务运行的内存池激活专用高速缓存。

    同样使用 WRKSYSSTS 命令(连续按 F11 三次,直到出现 Paging Option 栏),将 Paging Option 设为 *CALC,下面是一个例子:

DB2 UDB for iSeries 高校编程

本文“ODBC 连接”一节中谈到了高效访问 DB2 UDB for iSeries 的两个问题:扩展动态 SQL 和连接池。现在我们来看一看编程技术。读者采用这些技术可以进一步改善整个数据库的性能。注意,本节介绍的编码技术对所有数据库应用程序都是有效的,并不仅仅局限于 DB2 UDB for iSeries。

可重用的开放数据路径(Open Data Paths,ODP)

开放数据路径(ODP)是给定任务(或连接)中的特定 SQL 语句(如 OPEN、INSERT、UPDATE 和 DELETE)第一次执行时创建的 OS/400 内部对象。ODP 提供了到数据的直接链接,因此会发生 I/O 操作,创建 ODP 对象的过程对 CPU 和 IO 很敏感,因此只要可能,DB2 UDB for iSeries 运行时就会尝试使用已有的 ODP。比如,SQLCloseCursor() API 调用可能会关闭 SQL 游标,但是 ODP 会保留下来当下一次打开游标时再重用。这样可以显著地减少运行 SQL 语句的处理和响应时间。可重用 ODP 所要求的 CPU 资源通常是新建 ODP 的十分之一到二十分之一。因此,允许 DB2 UDB 运行时重用 ODP 的应用程序实现编程技术很重要。

对于 ODBC 或 JDBC 这样的动态接口,应该使用“一次准备、多次执行”的编程范型避免完全的开放性。就是说如果 SQL 语句要执行多次,开发人员应该只准备该语句一次,在以后的执行中重用准备好的语句。虽然 DB2 UDB 确实努力将文字转化成参数标记,以便重用类似的语句,但最佳编程实践是明确的实现参数标记,这样可以显著增加 ODP 重用的机会。图 8 所示的代码片段说明了如何实现“一次准备,多次运行”编程技术。


图 8.使用“一次准备,多次执行”编程技术

为了清晰起见,图 8 中已经去掉了错误处理代码。在 [1] 中,语句文本被赋予一个变量。注意 WHERE 子句中使用了参数标记。然后在 [2] 中准备该语句。参数的当前值在 [3] 中绑定到准备好的语句。准备好的语句在 [4] 中执行。第 [3] 步和 [4] 步可以再循环中重复执行。

大量删除

有时候应用程序需要从给定表中删除所有的记录,以便清空日志记录或者装入新的一个月的销售数据。这种情况下,强烈建议读者使用原生的 CLRPFM 命令,而不是 SQL DELETE 语句。DELETE 语句需要将每个记录标记为已删除,然后再进行大量的 I/O 操作。此外,后续的 INSERT 操作也慢得多,因为 DB2 UDB 引擎会首先尝试重用已删除的记录。下面的代码说明了如何从 ODBC 客户机调用 CLRPFM 本机命令:

strcpy((char *) SQLStmt, " CALL qsys.qcmdexc('CLRPFM 
FILE(DB2USER/COFFEES)',0000000028.00000)"); 
rc = SQLPrepare(StmtHandle, SQLStmt, SQL_NTS); 
rc = SQLExecute(StmtHandle); [1] 
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) 
{printError(ConHandle, StmtHandle);}

第 [1] 步,用两个参数调用系统存储过程 QCMDEXC。第一个参数包含在 iSeries 服务器上执行的本机命令,第二个参数包含命令文本的长度,采用 DECIMAL(15,5) 格式。

分块、存储过程和结果集

使用分块、存储过程和结果集减少与服务器之间的往返。关于 iSeries 的具体实现细节,请参阅 iSeries Information Center网站的 iSeries Access for Windows ODBC 一节(http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/rzaik/rzaikappodbc.htm)。





回页首


度量应用程序的性能

在应用程序性能测试方面,开发人员有很大的灵活性。可以在代码中放上标志,检查完成特定操作所需要的时间间隔。这样能够确定出现的任何性能问题。但有时候可能需要其他的工具帮助进行问题诊断。对于这个应用程序而言,对网络和数据库性能进行跟踪也很有必要。下面讨论如何捕获零散的网络信息,以及如何创建和分析数据库日志文件。

分析通信

本文中所用的示例设计在 Linux 分区中使用两个网络连接。一个物理网络连接用于和客户机的通信,另一个网络连接是 Linux 分区和 DB2 UDB for iSeries 分区之间的虚拟以太局域网络连接。 图 9 描述了通过运行应用服务器的 Linux 分区的信息的逻辑流向。网络接口名和数字是随意选择的,依赖于网络配置,也可以颠倒过来。


图 9. 通过接口的逻辑通信流

在以前,通过捕获应用程序例程中两个接口间交换的分组来分析应用程序的性能很有效。因为开发人员要捕获同一台服务器两个网络接口的数据,每次事务的时间戳是精确的,因此很容易进行比较。

下面的代码将捕获两个网络接口的 TCP/IP 数据并保存到 network.log 文件中。

# tcpdump > network.log

按网络接口将日志文件分成两个,以便区分收集到的信息,您可能需要更加谨慎(参见 图 9)。最简单的办法就是在服务器上使用两个会话,每个会话运行下面的一个命令:

# tcpdump –i eth0 > network_eth0.log 
# tcpdump –i eth1 > network_eth1.log

日志文件的输出可能如下所示:

.
.
.
11:46:18.820009 myappsvr.mycompany.com.32803 > 
myclient.mycompany.com.29838: . ack 38 win 5840 (DF) 
11:46:18.820351 myclient.mycompany.com.29838 > 
myappsvr.mycompany.com.32803: P 38:86(48) ack 1081 win 64455 (DF) 
11:46:18.820390 myappsvr.mycompany.com.32803 > 
myclient.mycompany.com.29838: . ack 86 win 5840 (DF) 
11:46:18.820478 myappsvr.mycompany.com.32803 > 
myclient.mycompany.com.29838: P 1081:1117(36) ack 86 win 5840 (DF)
.
.
.

根据这些时间戳,再加上对应用程序非常了解,开发人员可以确定信息“在线路上”进行传输所花费的时间。tcpdump 的主页是一个很好的资源,可以帮助您阅读这些文件。

分析 Linux

为了检查彻底,开发人员可能还希望了解应用程序运行的时候 Linux 发生了什么,以便发现异常的行为。可以使用剖析程序来做到这一点,其中有一个叫 OProfile 的剖析程序。OProfile 随 Red Hat Enterprise Linux 3 一起发布,通常默认安装。最新的 OProfile 源代码可以从 OProfilr 网站(http://oprofile.sourceforge.net/news/)上找到。通过 OProfile 这样的剖视程序,可以捕获一般 Linux 工具无法提供的特性剖视程序一般的功能包括:

  • 剖视中断处理器。
  • 描述应用程序及其共享库。
  • 报告系统的性能和行为。
  • 记录硬件的作用,比如缓冲失效。
  • 捕获指令级的剖视信息。

撰写本文的时候,OProfile 剖视程序有一个突出的缺点,即不能捕获 JIT 编译的 Java 方法。如果应用程序中使用了 Java 语言,OProfile 生成的结果可能会造成误解。有关的最新情况,请访问 OProfile 网站。

剖视的挑战之一是知道要寻找什么。好的办法是取得一个剖视文件,然后分析那些占用 CPU 时间最多的例程。观察那些毫无道理的消耗大量资源或者造成大量库重定位的例程(建议使用 应用服务器一节中使用的 -fpic 选项)。

分析数据库操作

一旦理解了 SQL 请求如何在 DB2 UDB for iSeries 上运行,您可能会问:“如何才能知道我的 SQL 语句被 SQL 运行时以有效的方式运行呢?”。答案很简单:使用工具。下面讨论 DB2 UDB for iSeries 中可以重要的几种最重要的工具。

启用调试信息的 Joblog

调试消息是写入任务日志的关于查询实现的信息。它们描述了查询的实现方法,如索引的使用、连接顺序、ODP 实现(可重用还是不能重用)等等。告诉 iSeries 服务器包含调试消息最简单的方法是在连接字符串中包含关键字 TRACE=4,比如:

char ConnectStr[512] = "DSN=os400;UID=db2user;PWD=test26t;TRACE=4;";

任何时候,服务器上都可能有大量的数据库服务器任务在活动。第一步是确定服务特定 ODBC 连接的任务。最简单的方法是在 OS/400 提示符下运行下面的 CL 命令:

WRKOBJLCK OBJ(DB2USER) OBJTYPE(*USRPRF)

其中,DB2USER 是用来连接 iSeries 服务器的用户配置文件。注意,连接建立后,QZDASOINIT 任务被分配给 ODBC 连接,因此开发人员需要在客户机应用程序中的 SQLDriverConnect API 调用下设置断点。

一旦出现 Work with Object Locks,在列出的惟一 QZDASOINIT 任务后面输入“5”(Work with Job),打开 Work with Job 对话框。选择选项 10 显示数据库服务器任务的任务日志。然后可以在任务日志中检索 DB2 UDB 运行时生成的所有消息。

数据库监控程序

通过数据库监控程序,特定查询或者每个查询的性能统计信息可以收集起来并生成不同的报表。比如,开发人员可以得到显示以下查询的报告:

  • 使用了大量系统资源。
  • 执行花费了很长时间。
  • 由于查询时间的限制没有执行。
  • 在执行过程中创建临时的关键访问路径。
  • 执行中使用查询排序。
  • 按照查询优化器建议的键创建逻辑文件能够执行得更快。

我们建议,如果服务器上有性能敏感的查询可以考虑使用数据库监控程序。关于如何采集和分析数据库监控程序记录的详细信息,请参阅“ Using AS/400 Database Monitor to Identify and Tune SQL Queries”(http://www.ibm.com/servers/eserver/iseries/benchmark/performance/pdf/tune_sql.pdf)白皮书。





回页首


应用程序性能测量和评估

在完成所有的设计、代码生成或者重新编译、性能优化之后,部署复杂应用程序的一个关键步骤是进行基准测试。我们要说的不是那些相互竞争的基准,而是基准测试的原则。这对于分区发挥的作用越来越大的 iSeries 环境而言尤其突出。因为分区允许共享和动态地重新安排处理器,所以应用程序的评估稍微复杂一点。在用户应用程序受限于 CPU 的情况下,建立一个基准比较处理器的分配和合理的并发用户数非常理想。图 10 是一个非常简单的例子。


图 10. 评估指南

虽然整个观点有些初级,但确实能够正确地预计应用程序的性能。此外,根据我们的经验,这类活动可以排除性能问题,是开发人员能够在不同的负荷和场景中努力测试应用程序。更多信息和相关基准,请参阅 iSeries Benchmark Center(http://www.ibm.com/servers/eserver/iseries/benchmark/cbc/index.html)。





回页首


结束语

高效访问 DB2 UDB for iSeries 是在 Linux on iSeries 分区中成功部署三层应用程序的关键因素之一。DB2 UDB for iSeries 是一种健壮而成熟的数据库,在数以千计的应用程序中得到成功应用。但是,您不应该假设在不同数据库上工作很好的数据库设计在 iSeries 服务器上也同样有效。每个数据库引起都有自己的特点,通常需要针对平台进行专门的 SQL 优化。因此,项目计划应该包含数据库优化活动的时间和资源。

还要注意的是,某些应用程序体系结构比另一些更适合于 Linux on iSeries 和 DB2 UDB for iSeries 运行时环境。特别是,要避免没有缓冲的、生命期短的数据库连接。“ODBC 连接”中已经说明,获得数据库连接从系统资源的角度来看是一个相当昂贵的过程。此外,给定的 SQL 语句通过新建的数据库连接第一次执行时,应用程序要付出创建开放数据路径(完全开放)的代价。因此,应用程序采用连接池机制至关重要。实现本文所述的最佳编程实践能够得到健壮、性价比更高的解决方案。

三层部署中的其他部分也影响性能。一定要用适当的 gcc 标志编译 Linux 应用程序。此外,开发人员应该注意生成的网络通信量,尤其是要考虑到数据库请求必须通过通信栈来发送。最后,应用程序的测量和剖视对于移植和创建都是极其重要的。



参考资料

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文


作者简介

Brent Baude 是 IBM eServer Solutions Enablement 小组的 Linux 顾问。他定居在明尼苏达州的 Rochester。Brent 的主要任务是帮助开发人员把应用程序移植到 Linux on POWER 平台上。在为 IBM 工作的同时,他同时还在 iSeries 开发实验室拥有几个不同的职位。您可以通过 baude@us.ibm.com 与他联系。


Jarek Miszczyk 是明尼苏达州 Rochester 的 Solutions Enablement 组织的高级软件工程师。他的使命是根据 DB2 UDB for iSeries 相关问题,为独立软件供应商、IBM 客户和其他 IBM 组织提供咨询服务。他还围绕着 iSeries 的方方面面,撰写并执教了大量 IBM 课程。Jarek 在计算机领域有 15 年的经验,他的专业领域涉及数据库编程、SQL 和数据库迁移。您可以通过 jarek@us.ibm.com 和他联系。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?







回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款