高级性能调优概念

了解关键系统领域和 JVM 调优

如果底层主机的配置不合适,即使是最好的应用程序,性能也会受损。本文讨论性能调优的四个关键方面以及在每个方面要注意的问题。另外,基于 Java™ 的应用程序还有其他性能调优需求,尤其是在垃圾收集方面。本文还讨论垃圾收集的相关信息。

Sean A. Walberg, 高级网络工程师

从 1994 开始,Sean Walberg 就一直在学术、企业和 Internet 服务提供者环境中从事 Linux 和 UNIX 系统的研究。在过去几年里,他撰写了大量有关系统管理的文章。



2009 年 6 月 29 日

可以通过修改许多服务器设置让它更好地处理工作负载。根据服务器负载性质的不同,文件服务器的调优不同于数据库服务器,两个应用服务器也可能采用不同的方式调优。调优涉及把有限的服务器资源分配给操作系统和应用程序的不同部分,从而让应用程序尽快做出响应。下面是调优要考虑的领域:

  • 中央处理单元 (CPU)
  • 内存
  • 磁盘(包括空间和访问速度)
  • 网络

这些方面经常会相互影响。例如,可以为缓存分配内存,这可以减少磁盘访问或通过网络的资源访问。本文的重点之一是与 Java 虚拟机 (JVM) 相关的内存调优。JVM 有自己的内存管理系统,必须监视和配置这个系统。

CPU

服务器的 CPU 会在等待某些事件方面花费很多时间。最常见的情况是等待磁盘返回数据。多任务机制允许 CPU 在等待时做其他事情。因此,如果主机在 CPU 方面花费大量时间,那么购买更快的 CPU 会提高性能。

vmstat 命令提供关于系统时间消耗的实时细分信息,sar 工具套件适合进行长期监视。如果这些工具显示 CPU 把大多数时间花费在用户空间,空闲周期非常少,就应该考虑采取措施。在这种情况下,要么把负载转移到其他服务器,要么提高 CPU 能力。

转移负载可能意味着在另一台服务器上运行批作业,或者把应用程序负载分配给多台服务器。后一种方法是最理想的,这称为水平扩展。如果必须提高 CPU 能力,那么可以进行物理升级,比如添加更多的 CPU;如果处于虚拟化环境,还可以重新分配更多资源。

一些负载本身不适合并行处理,所以跨多个服务器分配负载或添加更多 CPU 不会有帮助。在这种情况下,要使用更快的 CPU 并花时间优化底层代码,减少运行它所需的 CPU 周期。

内存

内存调优涉及许多方面。最简单的调优措施是确保 RAM 足以容纳应用程序,而不需要使用交换空间。操作系统的虚拟内存子系统允许应用程序分配的内存超过系统上实际存在的内存量,不足的部分由磁盘上的临时存储组成。与直接访问 RAM 中的内存块相比,把内存块交换到磁盘并交换回来要慢得多,所以一般情况下应该避免这种做法。

虚拟内存子系统需要调优,因为在系统用完内存之前和发生某些事件时,可能会把内存块写到磁盘,这时不得不使用交换空间。要检查的主要是什么时候使用虚拟内存。随着 UNIX® 系统上的空闲内存被逐渐分配掉,内核最终会发现它必须要寻找可以交换出去的内存页面。在此之后,如果内核预计必须为请求内存的进程分配内存,它就会开始把一些页面交换到磁盘。如果您知道内存足以处理工作负载,最好推迟这两种交换活动。

在 Solaris™ 上,通过 /etc/system 中的可调项来调整内存。在 IBM® AIX® 操作系统上,使用 vmo 命令。在 Linux® 中,使用 /etc/sysctl.conf。它们的作用会随着操作系统的发展而变化,所以在做任何修改之前要仔细研究。

最后,安装更多内存让文件系统可以把文件和元数据缓存在内存中。大多数 UNIX 系统会尝试用空闲内存执行缓存,这就是系统常常看起来没有空闲内存的原因。缓存可以减少磁盘活动,这对于 Web 服务器等工作负载非常重要。

磁盘

磁盘比内存慢得多,所以过多的磁盘活动是许多应用程序性能低下的原因。磁盘活动可能源于交换,也可能源于应用程序或操作系统的请求。过多的日志记录活动也会争用磁盘。

发现磁盘瓶颈的最佳工具是 iostat。这个工具可以指出在特定时间点发生了多少读写操作,以及磁盘控制器的饱和程度有多大。如果有多个磁盘,那么把负载分配到不同的磁盘上是加快读写速度的有效方法,因为磁盘延迟的最大组成部分是寻道时间。不断增长的文件(比如日志文件和数据库日志)应该放在单独的磁盘上,与应用程序的磁盘和数据库分开。

vmstatiostat 报告系统在等待 IO 方面花费的时间百分比,也就是 CPU 空闲而系统正在等待 IO 返回的时间。iowait 值高就意味着磁盘缓慢或负载过大。

与磁盘密切相关的是可以打开的文件描述符数量。如果用光了文件描述符,那么打开文件的操作就会失败。通常,ulimit 命令可以增加可用的文件描述符数量,但是操作系统对于 ulimit 可能有内核限制。

网络

网络对于大多数应用程序都很重要,因为网络在服务器和客户机之间来回传输数据。网络慢常常导致应用程序看起来响应缓慢。应该做的第一件事是,确保所有服务器使用全双工和最高的网络速度,并相应地匹配交换机端口。交换机和服务器之间的速度和双工不匹配是网络问题的常见原因。

操作系统会为网络资源分配各种缓冲区。例如,操作系统为每个 TCP 连接维护 TCP 发送队列。这个队列保存应用程序已经发送,但是还没有得到远程端确认的数据(根据未确认数据包的数量,一些数据可能还未发送到网络)。如果这个队列满了,就不允许应用程序发送更多数据,直到清理完积压的队列为止。

可以用 netstat -s 寻找缓存区拥挤的迹象,这个命令输出网络计数器的列表。其中包含 “queue” 或 “overflow” 的内容都与 TCP 队列相关,应该监视它们。这些计数器一般只在系统引导时重置,所以应该更关注随时间增长的数字。

如果 netstat -an 表明大量连接处于等待状态(比如 CLOSE_WAITFIN_WAIT_1),那么由于所有系统资源都被这些连接占用,可能会导致无法建立新连接。在这种情况下,可以考虑减少连接超时值,这些值控制操作系统维持连接多长时间;这可以使用 Solaris 的 ndd 或 AIX 的 no 来设置。

深入研究 Java 内存

前面几节讨论了需要调优的四个系统领域。其中之一是内存。在 Java 应用程序环境中,服务器把内存分配给 Java 进程,Java 进程负责运行应用程序代码。这个 Java 进程就是 JVM,它负责把内存分配给底层应用程序。

在操作系统级上,可能看到 1GB 内存被分配给一个 Java 进程。在这个进程内部,JVM 管理堆,堆为新对象提供内存。在创建对象时,对象被放在堆上。在销毁对象时,它们仍然留在堆上。JVM 会运行一个称为垃圾收集 的过程,垃圾收集标出所有创建的对象,然后清理堆的其余部分供以后的分配使用。在此时,堆可以扩展(如果垃圾收集没有回收新分配所需的足够内存)或收缩(如果满足特定条件,使 JVM 认为堆太大了)。

根据这个简化的垃圾收集定义可以推断出,在执行垃圾收集时系统不会执行任何应用程序工作。在运行垃圾收集期间,JVM 实际上会暂停。因此,许多 Java 调优措施都涉及决定堆的最佳内存大小以及调整垃圾收集过程。

垃圾收集过程调优的基本思路是,了解运行垃圾收集的频率以及触发它的条件,然后通过修改 JVM 设置尽可能降低垃圾收集的影响。

收集垃圾收集信息

为了了解垃圾收集对应用程序的影响,首先要收集关于何时及如何执行垃圾收集的信息。在 JVM 中启用详细垃圾收集日志记录,这会开始记录垃圾收集活动。在 IBM WebSphere™ Application Server 中,可以在管理控制台中找到这个设置:在 Integrated Solutions Console 中导航到 Application servers > server name > Process Definition > Java Virtual Machine,选择 Verbose Garbage Collection

还可以用 -verbose:gc 参数启动 JVM(这也是 Integrated Solutions Console 选项在幕后采用的方法)。无论采用哪种方法,JVM 的输出现在都会包含垃圾收集信息。

对于启用详细垃圾收集日志记录,糟糕的方面是不同厂商采用的文件格式不一致,甚至在同一厂商提供的不同版本之间也可能不一致。例如,IBM 的 Java Runtime Environment (JRE) 6.0 采用详细的 Extensible Markup Language (XML) 文件格式。而 Sun Microsystems 的 HotSpot JVM 使用简明的单行格式,有时候需要启用更多命令行参数,才能得到所需的信息。

了解垃圾收集数据的意义

启用垃圾收集器的日志记录之后,在正常负载下运行应用程序。然后,研究垃圾收集日志。可以看到堆的大小从最初的分配开始增长,最终稳定在某一范围内。然后,可以使用这个范围内的某个值作为堆的初始大小,这会消除堆增长到稳定状态导致的初始延迟。

垃圾收集日志还会指出发生垃圾收集的时间以及垃圾收集花费的时间。如果发现垃圾收集的运行时间太长,可以考虑让 JVM 使用另一种垃圾收集算法(具体细节取决于 JVM 的版本和厂商)。根据这些时间戳,还可以计算出系统在垃圾收集方面花费的时间百分比,可以用这个指标比较各种 JVM 设置。

如果发现堆不断增长和收缩,可以修改 MinHeapFreeMaxHeapFree 值,JVM 使用它们决定什么时候扩展或收缩堆。

随着 JVM 的发展,与垃圾收集相关的性能也会变化。一定要通过您的 JVM 手册了解当前的调优参数。

调优的优先次序

对于在为 WebSphere Application Server 调整 UNIX 服务器时应该检查哪些方面,IBM 给出了一些建议。

首先,确保服务器具有所需的资源:CPU、磁盘、内存和网络。这些是最基本的。

接下来,了解应用程序的垃圾收集需求并相应地调整 JVM。这可能需要回到前一步,确保具有按所需方式运行应用程序的足够内存。

确保适当地设置应用服务器队列,让应用服务器只处理它能够处理的请求。当 Web 服务器把请求交给应用服务器时,它会进入一个队列。如果允许太多的连接连接到应用程序,每个用户都会体验到糟糕的性能。因此,过剩的连接应该在 Web 服务器上排队,而不要在 WebSphere Application Server 上排队。

最后,可以使用多种缓存技术,比如数据库中的预备语句、Enterprise JavaBean (EJB) 技术和线程缓存。如果不断清理缓存,从而为新内容让出空间,就应该考虑增加缓存大小。

结束语

计算机的资源分为 CPU、磁盘、内存和网络。调优工作应该度量这些资源,然后在应用程序、应用服务器和服务器中做相应的调整,确保不出现资源争用。

JVM 管理自己的堆并通过垃圾收集过程清理堆。这方面的调优包括确保堆可以增长到应用程序需要的大小,以及通过调整垃圾收集参数避免垃圾收集的影响过大。

进行垃圾收集调优的主要工具是详细垃圾收集日志记录,这会记录每个垃圾收集活动。可以通过日志了解垃圾收集花费的时间以及执行收集的原因。

参考资料

学习

  • Sun Microsystems 的垃圾收集例程的文档(v5v6)提供关于各种垃圾收集算法的工作方式及其适用场合的信息。
  • Java Diagnostics Guide 深入介绍了 IBM JVM 的详细垃圾收集日志记录的 XML 格式。
  • 阅读针对 UNIX 性能调优 的 WebSphere Application Server 文档。
  • Sensible Sanitation -- Understanding the IBM Java Garbage Collector, Part 1: Object allocation”是关于 JVM 垃圾收集的三篇系列文章的第一篇。这篇文章有点儿过时了,因为它不包含一些最新的垃圾收集算法,但是它对垃圾收集概念和堆内存分配方法的阐述仍然是有意义的。
  • 对于系统调优,了解如何使用 vmstat 命令是非常重要的。
  • 这份关于 AIX 性能调优 的文档包含用来在 AIX 服务器上寻找和解决瓶颈的许多命令。
  • 如果运行 Solaris,可以参考关于 Solaris 系统调优 的 IBM 文档。
  • 如果运行 AIX,应该阅读关于 AIX 系统调优 的文档。
  • 如果使用 WebSphere,那么必须阅读 IBM 的 WebSphere Application Server V6 Scalability and Performance Handbook。它的内容多达 1100 页,提供了关于如何调整 WebSphere 和其他组件以及如何编写可伸缩性更好的应用程序的建议。
  • 另一份 IBM RedBook Running IBM WebSphere Application Server on System p and AIX: Optimization and Best Practices 讨论 WebSphere 应用程序的水平扩展和垂直扩展。这个文档还讨论如何调整应用服务器和操作系统。
  • 技术书店 浏览关于这些主题和其他技术主题的图书。
  • AIX and UNIX 专区:developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。
  • AIX and UNIX 新手入门:访问“AIX and UNIX 新手入门”页面可了解更多关于 AIX 和 UNIX 的内容。
  • AIX and UNIX 专题汇总:AIX and UNIX 专区已经为您推出了很多的技术专题,为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您,为了方便您的访问,我们在这里为您把本专区的所有专题进行汇总,让您更方便的找到您需要的内容。
  • developerWorks 技术活动网络广播:随时关注 developerWorks 技术活动和网络广播。
  • Podcasts:收听 Podcast 并了解 IBM 技术专家的最新想法。

获得产品和技术

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=404715
ArticleTitle=高级性能调优概念
publish-date=06292009