改善 Linux 性能的第一步是对其进行量化。但如何精确地对 Linux 的性能或与它相当的系统性能进行量化呢?在本文中,IBM Linux 技术中心的成员描述了他们在去年底对 Linux 2.4 和 2.5 内核所做的几个基准程序测试,就这些专家经验,以飨读者。
目前,Linux 操作系统是最成功的开放源码项目之一。Linux 作为 Web 服务器操作系统,展示了其高可靠性,在 Web 服务器市场,它占据了很大的份额。这些 Web 服务器通常是低端及位于中间档次的系统,带有最多可达 4 路的对称多处理器(SMP);而企业级系统有更复杂的需求,譬如需要更多的处理器个数和 I/O 配置以及大的内存和带宽。为了使 Linux 为进入企业环境而作好准备,以及能够作为商业性应用进入 SMP 市场,与商业 UNIX 系统相比,它的 SMP 可伸缩性、磁盘和网络 I/O 性能、调度程序和虚拟内存管理器必须得到改善。
Linux 可伸缩性研究计划(Linux Scalability Effort,LSE)(请参阅参考资料中的链接)是一个开放源码项目,解决了用于企业级机器的 Linux 内核问题,这些机器的可伸缩性达到 8 路或更高。
IBM Linux 技术中心(Linux Technology Center,LTC)的 Linux 性能团队(请参阅参考资料的相关链接)积极地参与了 LSE 活动。此外,他们的目标是,通过改进 Linux 内核性能(尤其针对 SMP 可伸缩性)而使 Linux 更优秀。
本文描述了在着重平台无关性问题的同时,该团队在测量、分析与改进 Linux 内核性能和可伸缩性上所采用的策略和方法。该团队使用了一套基准测试程序来完成此项任务。这些基准测试程序考虑到了各种工作负载,其中包括 Web 服务、数据库和文件服务。此外,我们还将向您展示每个基准测试程序所着重的各个内核组件(例如,磁盘 I/O 子系统)。
分析方法 这里我们讨论用来量化针对 SMP 可伸缩性的 Linux 性能的分析方法。如果您愿意,可以直接跳到基准测试程序结果这一节。
我们用来改进 Linux 性能和可伸缩性的策略包括:运行几个业界接受的和组件级的基准测试程序,选择合适的硬件和软件,开发基准测试程序运行规则,设定性能和可伸缩性目标,以及测量、分析和改进性能和可伸缩性。在这一节中将详细讲述这些过程。
性能被定义为单处理器(UP)或 SMP 上的原始吞吐量。我们将 SMP 可伸缩性(CPU)和资源可伸缩性(例如,网络连接数目)区别开来。
硬件和软件 这项工作的大部分都使用 IA-32(即 x86)体系结构,从 1 个到 8 个处理器。我们还研究了与为将来之用的非一致内存访问(NUMA)IA-32 和 NUMA IA-64 体系结构相关的问题。硬件的选择通常是根据基准测试程序和相关工作负载的选择。软件的选择要与 IBM 的 Linux 中间件策略和/或开放源码中间件相结合。例如:
数据库
我们采用查询数据库基准测试程序,而在硬件上,采用带大磁盘配置的 8 路 SMP 系统。数据库软件采用 IBM DB2 for Linux,SCSI 控制器是 IBM ServeRAID 4H。这个数据库是针对 8 路 SMP。
SMB 文件服务
基准测试程序是 NetBench,硬件是 4 路 SMP 系统,驱动 SMP 服务器的客户机可多达 48 个。中间件是 Samba(开放源码)。SMB 文件服务是针对 4 路 SMP。
Web 服务
基准测试程序是 SPECweb99,硬件是 8 路 SMP,并带有大内存配置,客户机可达 32 个。这个基准测试仅用于研究目的,不做它用(有关这方面的更多细节,请参阅基准测试程序这一节)。Web 服务器是 Apache,它是 IBM HTTP 服务器的基础。我们选择 8 路 SMP 是为了研究可伸缩性,而选择 Apache 是因为它支持对下一代 posix 线程(NGPT)的测量和分析(请参阅参考资料)。此外,它是开放源码,而且是最流行的 Web 服务器。
Linux 内核版本
采用哪个版本的 Linux kernel.org 内核(2.2.x、2.4.x 或 2.5.x)取决于基准测试程序;这将在基准测试程序一节做进一步讨论。为了简化管理,所选的 Linux 分发版是 Red Hat 7.1 或 7.2。我们的重点是内核性能,不是分发版的性能:我们用要评估的 kernel.org 内核和补丁替代了 Red Hat 内核。
运行规则 在设置基准测试程序期间,我们开发了运行规则以详细地指出如何安装、配置和运行基准测试程序,以及如何解释结果。这些运行规则的目的如下:
定义度量,使用此度量来测量基准测试程序的性能和可伸缩性(例如,消息/秒)。
确保基准测试程序的结果适合于测量工作负载和内核组件的性能和可伸缩性。
提供文档化的说明,这将使其他人可以重复该性能测试。
定义所收集的数据集,以便可以分析被测系统(System Under Tes,SUT)的性能和可伸缩性,从而确定瓶颈在哪里。
设定目标 针对某个基准测试程序的性能及可伸缩性与具体的 SUT(硬件和软件配置)有关。设定性能和可伸缩性目标需要:
基线测量,用来确定针对基线内核版本的基准测试程序的性能。然后计算基线可伸缩性。
最初的性能分析,用来确定增强性能的可行方向(例如,显示调度程序非常忙的概要文件可能会建议尝试 O(1) 调度程序)。
将基线结果与类似的已公布结果进行比较(例如,在 spec.org 上查找类似 8 路 SMP 上相同 Web 服务器上的 SPECweb99 公开结果)。
如果没有可用的外部公开结果,则可以尝试使用内部结果。还可以尝试与其它操作系统进行比较。给定具有竞争性的数据和基线,然后选择 UP 和 SMP 机器的性能目标。
最后,可以声明应用程序变更了目标。例如,如果知道某个应用程序采用异步 I/O 方式效率不高,则可以通过假定改变 I/O 方法,公布该性能目标。
调优、测量和分析 在做任何测量之前,需要调优硬件和软件配置。调优和测量是一个不断循环的调优和测量过程。它涉及了系统组件(譬如 CPU 利用率和内存使用率)的测量,还可能涉及系统硬件参数、系统资源参数和中间件参数的调整。调优是性能分析的第一步中的环节。没有调优,测量出的结果可能会使人产生误解;即,这些结果可能不会指出内核的限制,而显示出别的问题。
根据运行规则来运行基准测试程序,从而可以根据已定义的性能度量来测量性能和可伸缩性。对给定机器计算 SMP 可伸缩性时,可以选择根据 UP 内核的性能来计算此度量值,也可以选择根据 SMP 内核(其中处理器数目设为 1 — 一个处理器)的性能来计算它。我们决定使用 UP 测量来计算 SMP 可伸缩性,这样可以更精确地反映 SMP 内核性能的改进。
使用前面确定下来的 Linux 内核版本来测量基线。对于大多数基准测试程序,需要测量 UP 和 SMP 基线。对于少数基准测试程序,只需测量 8 路 SMP 性能,因为收集 UP 性能信息受到时间限制。大多数其它基准测试程序测量在特定时间段内完成的工作量,在 UP 上的测量时间不超过在 8 路 SMP 上的测量时间。
分析 SUT(被测系统)的性能和可伸缩性所需的第一步是理解被测试的基准测试程序和工作负载。最初的性能分析是针对经过调优的系统而作出的。有时,分析揭示了对调优参数的其它修改。
对 SUT 性能和可伸缩性的分析需要一组性能工具。我们的策略是尽可能地使用开放源码社区(Open Source community,OSC)的工具。这使我们可以将分析数据在 OSC 上公布,以说明性能和可伸缩性上的瓶颈。这也使 OSC 中的成员可以用工具重复我们的结果,或者在用该工具对另一个应用程序做完试验之后,能够理解这些结果。如果开发出专门的性能工具来更好地理解某个具体性能瓶颈,则随后通常会将此专门的性能工具在 QSC 上共享。这些专门的性能工具通常是一些简单工具,它们为特定的 Linux 内核组件提供了测试手段。我们所使用的性能工具包括:
/proc 文件系统
meminfo、slabinfo、中断、网络状态、I/O 状态等。
SGI 的 lockmeter
来自 SMP 锁分析
SGI 的内核概要分析器(kernprof)
基于时间的概要分析、基于性能计数器概要分析、仅关于内核空间的带注释的调用图(annotated call graph,ACG)
IBM 跟踪工具
针对用户空间和系统空间的单步(mtrace)并同时基于时间和基于性能计数器的概要分析
开发专门的性能工具,以进一步理解系统具体某个方面。
例如:
sstat
收集调度程序统计信息
schedret
确定哪些内核功能因调查空闲时间而阻塞了
acgparse
后处理 kernprof ACG
复制进/出工具
确定缓冲区的调整、复制大小和复制进/出算法的 CPU 利用率
然后使用性能分析数据来确定性能和可伸缩性的瓶颈。需要对 SUT 有宽泛的理解,并要对基准测试程序所着重的 Linux 内核组件有更具体的理解,从而理解性能瓶颈存在于何处。还必须理解造成瓶颈的 Linux 内核源代码。此外,我们需要与 LTC Linux 内核开发团队和 OSC(开放源码社区)紧密合作,以便开发补丁来修正瓶颈。
退出策略 对 Linux 内核性能的评估可能需要运行基准测试程序,然后分析结果来确定性能和可伸缩性的瓶颈,接着将补丁集成进 Linux 内核来解决所有这些瓶颈,最后再次运行该基准测试程序,这是一个周而复始的过程。作为一名性能团队成员,要与 Linux 内核开发团队或 OSC 通力合作,通过在 OSC 查找现有的补丁或者开发新的补丁来获取补丁。有一组用来确定何时 Linux 已经“足够好了”和可以结束该过程的标准。
首先,如果我们已经达到了目标,并且,针对某个具体基准测试程序,不存在需要解决的任何突出的 Linux 内核问题(解决这些问题可以很大程度地改善