下载本文的PDF版本 PDF

隐藏在眼皮底下

软件可观察性的改进可以帮助您诊断最棘手的性能问题。

BRYAN CANTRILL,SUN MICROSYSTEMS

1997年12月,Sun Microsystems 刚刚发布了其新的旗舰机器:一台 64 处理器对称多处理器,支持高达 64 GB 的内存和数千个 I/O 设备。与任何新机器发布一样,Sun 正在疯狂地进行基准测试,以证明该机器的性能。虽然基准测试总体上令人印象深刻,但其中有一个特别的基准测试——一个特别复杂的基准测试,涉及多台机器——表现出出乎意料的低性能。基准测试机器——一个完全装满机架的庞然大物,配置了最多的 64 个处理器——偶尔会神秘地分心:基准测试活动几乎停止,但操作系统内核仍然忙个不停。在花费了数分钟进行未知工作后,操作系统突然恢复正常:基准测试活动将全速恢复并运行完成。运行基准测试的人可以看到机器正朝着打破世界纪录的方向前进,但这些长达数分钟的未知内核活动足以成为第一名和最后一名之间的差距。

鉴于基准测试和机器的重要性,Sun 的顶级开发和支持工程师被召集起来,并围绕这个问题在全球各地昼夜不停地工作。从问题的最初症状——网络堆栈中的高锁争用——开始,问题的进展非常缓慢和痛苦。根据现有数据,会形成一个假设,但由于没有办法在不收集额外数据的情况下探索该假设,因此必须创建和加载自定义数据收集内核模块。创建这些模块是一项精细的工作。从假设创建到仪表化和分析的整个周期需要数小时——这还是假设没有犯任何错误。错误是痛苦的,因为在创建自定义模块时出现的任何错误都会导致重启——而这台特定机器和配置的重启大约需要 90 分钟。

虽然对问题的迭代揭示了可以改进网络堆栈以缓解观察到的症状的几种方法,但花了将近一周的时间才确定真正的根本原因:基准测试机器被错误地配置为充当路由器。通常,这不会成为问题,但由于实验室其他地方的间歇性路由器故障,基准测试机器偶尔会开始在与基准测试相关的另外两台机器之间疯狂地路由数据包。这种路由活动会在网络堆栈中引起足够的争用,迫使系统进入一种以前从未见过的故障模式——这种模式又引发了更多的争用。

这是一个显而易见的问题吗?当然,事后看来是这样。但是,问题的级联症状与根本原因相去甚远,以至于如果不修改系统本身,就不可能看到更大的问题。也许最令人不安的是,这个问题相对简单,只涉及相对较少的软件层。如果软件堆栈的更多组件参与其中——如果必须在多个层面上修改系统才能观察到它——那么诊断起来将呈指数级地困难。

这里更大的问题是软件可观察性,或者更准确地说,是其明显的缺乏。我们构建了令人难以置信的复杂系统,但我们却看不到它们,从而使明显的性能问题在我们的系统中光天化日之下隐藏起来。我们是如何走到这一步的?又能做些什么呢?

问题的根源

软件可观察性问题的起源,与许多其他软件问题一样,可以在软件作为信息和机器的奇怪双重性中找到:软件只有物理表示,而没有物理表现。也就是说,运行中的软件不会反射光,也不会散发热量,也不会吸引质量,也不会具有任何其他我们可以用来观察它的物理属性。在古代,计算机通过具有显式模式来解决这个问题,在这些模式中,每个指令在执行时都会被指示出来。在微处理器的时代——以及每秒执行数十亿条指令的能力——这种设施早已变得不切实际,甚至不可能实现。因此,没有物理方法来确定正在执行哪些指令;查看正在执行的软件的唯一方法是修改软件本身。软件工程师长期以来一直这样做,添加允许他们的软件可以选择性地被看到的构造。虽然确切的表现形式各不相同,但这些构造通常看起来像这样

 if (tracing_enabled)
printf(“we got here!\n”);

这个概念有很多变体——例如,一段数据可以记录到环形缓冲区中,而不是显式打印,或者条件可以从环境变量而不是静态变量派生——但共同的想法是基于数据值的条件执行。这种性质的构造有一个不幸的属性:即使它们没有被使用,它们也会使系统变慢。也就是说,仅仅是条件执行的存在就会引起负载、比较和分支。虽然显然偶尔执行一次不会有问题,但如果广泛使用这些指令,成本就会变得难以承受:如果有人要在每个函数或每个基本块中都塞满这种构造,系统就会慢到无法交付。因此,保留这种构造已成为一种常见的软件工程实践,但要使用诸如条件编译之类的技术自动将其从生产代码中剥离。虽然这允许基础设施保留下来,但不幸的是,它将软件分叉为两个版本:一个可以被看到的版本,用于开发和测试;另一个无法被看到版本,用于交付或部署到生产环境。

这引发了一个悖论:性能问题越来越可能在生产环境中被看到,但只有在开发环境中才能被理解。为了解决在生产环境中看到的性能问题,因此必须在开发或测试环境中重现该问题。在软件系统中,与在任何足够复杂的系统中一样,不相关的病理可能会表现出相同的症状:重现症状(例如,高 CPU 负载、繁重的 I/O 流量、长延迟事务等)并不能保证重现相同的根本问题。用 IT 的行话来表达这种现象,您可能听到或说过这样的话

“好消息:我们能够在开发环境中重现它,并且我们认为我们找到了问题。开发环境有一个修复程序,我们正在安排今晚停机将其投入生产环境。让我们祈祷一切顺利……”

结果第二天就听到类似这样的话

“嘿,是的,关于那个修复程序……嗯,好消息是我们今天早上速度更快了;坏消息是我们只快了大约 3%。所以又要回到作战室了……”

如果这听起来出奇地熟悉,那是因为您已经陷入了试图通过在其他地方重现其症状来理解生产问题的陷阱:您找到了一个问题,但那不是真正的问题。

但是等等,情况更糟

生产软件中固有的可观察性不足已经够糟糕了,但是软件抽象的分层使性能问题更加尖锐。通常,软件抽象是一件好事,因为正是抽象使人们能够在不必开发应用程序所依赖的 Web 服务器、应用程序服务器、数据库服务器和操作系统的情况下开发应用程序。然而,这种力量也有阴暗面:在更高的抽象层进行开发时,更容易在系统中意外地引发意外或不必要的工作。这是同义反复的真理:要处于更高的抽象层,更少的代码必须引发更多的工作,这意味着只需一小步失误就可能引发更多意想不到的后果。

不幸的是,这种不必要或意外的工作往往会随着它在抽象堆栈中级联而成倍增加,以至于性能问题通常首先在堆栈的最底层被理解或表征,表现为高 CPU 利用率、严重的内存压力、异常的 I/O 活动、过度的网络流量等。尽管是更高层软件的后果,但堆栈最底层的症状很可能最直接地归因于次底层中的活动——例如,操作系统或数据库。

这提出了另一个悖论:系统性能问题通常在最高的抽象层引入,但它们通常首先在最低的抽象层遇到和归因。正是由于这个悖论,我们采纳了这样一种神话,即性能提升的途径几乎完全在于更快的硬件:更快的 CPU、更多的网络带宽等。当这失败时,我们已经教会自己转向堆栈的下一层:要求更快的操作系统、更快的数据库和更好的编译器。改进这些组件无疑会提高性能,但(用一个可能不敏感的比喻)这相当于捕猎害虫:依赖堆栈最底层的相对较小的迭代改进相当于试图靠松鼠和臭鼬之类的东西养家糊口。如果我们能够向上移动堆栈——如果我们能够找到潜在的性能问题,而不仅仅是解决它们的症状——我们就可以释放更可观的性能提升。这肯定是更大的猎物;通过关注堆栈中更高层次的性能问题,我们可以从捕猎害虫转变为捕猎牛——体型大、行动迟缓、愚笨、美味的牛。

解决方案的约束

为了在其原生栖息地捕猎牛,可观察性基础设施的重点必须进行两个深刻的转变:从开发到生产,以及从程序到系统。这些转变有几个重要的含义。首先,从开发到生产的转变意味着可观察性基础设施必须具有零禁用探针效应:仅仅观察系统的能力绝不能使交付的系统变得更慢。这种约束只允许一个真正的解决方案:软件在交付时必须经过优化,并且——当人们希望观察它时——必须动态修改软件。此外,从程序到系统的转变要求整个堆栈都必须能够以这种方式动态地进行仪表化,从操作系统的深处,到系统库,再到更高层语言和环境的崇高高度。不得依赖编译时选项、拥有源代码、重启组件等;必须假设第一次要观察一段软件时,该软件已经在生产环境中运行。

以这种方式动态地仪表化生产系统是一个可怕的主张,尤其是在将操作系统内核纳入其中时。这引导我们得出从开发到生产的重点转变的最重要含义:可观察性基础设施必须绝对安全。这种安全约束怎么强调都不过分:在生产系统中,停机始终是不可接受的,即使是由操作员错误导致的停机也可能像系统一样受到指责。如果工具的使用以任何方式与生产停机有关,则该工具很可能永远被生产环境所禁止。可观察性基础设施中的安全性,就像操作系统中的安全性一样,不能是事后才考虑的事情:它必须被视为架构的绝对、不可协商的约束。

一种解决方案:DTrace

在 Sun,我们开发了 DTrace,一种用于生产系统动态仪表化的工具。DTrace 与先前工作的最明显区别在于它专注于生产系统,尤其是它严格遵守安全约束。虽然它是操作系统的一个组件(最初是为 Solaris 10 开发的),但 DTrace 本身是开源的,因此可以移植到其他系统(特别是,已经启动了将 DTrace 移植到 FreeBSD 的项目 1)。DTrace 是一个复杂的系统(有关更多信息,请参阅 2004 年 Usenix 会议 2 的 Cantrill、Shapiro 和 Leventhal 以及 Solaris 动态跟踪指南 3),但值得阐明其更高层次的原则以及这些原则如何指导其架构的演变。

为了确保零禁用探针效应,DTrace 的设计围绕动态仪表化的思想。虽然动态仪表化的具体技术通常特定于指令集且晦涩难懂,但它们共享一个通用原则:它们修改正在运行的代码,以将控制流重新定向到拦截代码主体,该代码主体收集一些信息,然后将控制流返回到刚好超过仪表化点的位置。重新定向控制的机制各不相同,但它通常是一条指令,要么发出软件陷阱,要么无条件分支到拦截代码。在共享这个通用原则的同时,动态仪表化技术也共享一个共同的缺点:没有一种技术可以在系统中的所有上下文中工作。也就是说,在任何系统中,都有一些上下文过于敏感而无法动态仪表化。(这些上下文通常包括用于中断处理、上下文切换或同步的底层代码。)

因此,在遵守安全约束的同时仍然允许动态仪表化带来了一些挑战:如何在不损害生产系统所需的安全性的情况下,提供动态仪表化的灵活性?在 DTrace 中,我们通过将系统仪表化的方式与使用该数据的框架分离来实现这一点。仪表化系统的方法在于提供程序;这些提供程序通过 DTrace 框架提供探针。因此,仪表化的安全性成为提供程序的责任,提供程序只发布那些可以安全启用的探针。通过限制 DTrace 使用者仅启用已发布的探针,系统——而不是用户——负责确定可以安全地仪表化哪些内容。这是一种折衷方案,因为它以一定程度上失去灵活性为代价:例如,当决定特定代码主体无法仪表化时,可能会发现提供程序不必要地保守。为了确保用户不会意外或故意牺牲系统完整性,这种微小的灵活性损失是必要的。这是任何工具在用于生产系统之前必须能够做出的保证。

提供程序实现了仪表化系统不同部分的机制,但如何对仪表化采取行动呢?也就是说,当仪表化系统的组件时,人们希望采取什么行动?我们使用一些早于 DTrace 的更原始的跟踪工具的经验常常让我们感到沮丧:似乎总是我们想要在给定点获得的数据刚好超出所提供的数据。在设计 DTrace 时,我们希望通过使操作完全可编程来消除这些挫败感。

这立即暗示了两类架构决策:首先,应该用什么语言来指定操作?其次,如何设计系统以确保这些可编程操作以安全的方式执行?鉴于安全性是我们的约束,我们首先解决了后者:为了允许可编程操作在任意上下文中安全地执行,很明显我们需要开发一个虚拟机,它可以充当自定义编译器的目标指令集。这一点很清楚,因为另一种选择——在内核中本地执行用户指定的代码——从安全角度来看是站不住脚的:即使您可以实现大量的静态分析来确保本机代码不执行非法操作,您仍然会遇到停机问题的棘手性。

因此,我们开发了一个简单的、专门构建的虚拟机,旨在在操作系统内核中安全地执行用户指定的代码,而不会产生副作用。通过仔细限制指令集架构来确保安全性:我们的虚拟指令集没有向后分支,仅支持对运行时中定义的子例程的调用,不允许任意存储等。(请注意,我们显然没有解决停机问题;我们只是通过设计一个不允许图灵完备语言的虚拟机来避免了它。)重要的是,虚拟机确实允许任意加载;对未映射内存(或更糟的是,即使加载也可能产生副作用的内存映射设备)的加载会被捕获、标记并优雅地处理。

凭借安全地执行任意操作的能力,我们可以专注于设计应该在其中表达这些操作的语言。为此,我们开发了 D,一种类似于 C 的语言,具有特定于 DTrace 的扩展,例如关联数组、线程局部变量等。D 的设计反映了安全约束:它明确缺乏循环结构、用户定义的函数、对任意地址的存储以及其他可能损害安全性的功能。由于我们的虚拟机具有安全加载的机制,D 可以(并且确实)允许类似 C 的指针追踪。

在动态仪表化和任意操作的安全基础上,接下来的系列问题集中在数据管理上。最明显的是,我们需要一种机制来过滤掉源头处不需要的数据。为此,我们添加了谓词的概念:附加到操作的条件 D 表达式,使得只有当表达式评估为真时才会执行该操作。谓词,结合 D 的强大功能和 DTrace 的异构仪表化,允许进行复杂的过滤。例如,图 1 显示了一个脚本,该脚本使用谓词、线程局部变量以及用户级和内核级代码的提供程序来跟踪流控制通过应用程序并进入操作系统内核;图 2 显示了运行此脚本的输出。

如图 2 所示,DTrace 允许能够穿透抽象堆栈中的不同组件,甚至跨越保护边界。任何可观察性框架不仅必须能够穿透组件层,而且还必须允许在交互中看到模式。为了在 DTrace 中实现这一点,我们将数据聚合提升为一流的概念:DTrace 不是必须用要后处理的数据来阻塞系统,而是允许数据以任意 n 元组为键,并在源头进行聚合。这可以将数据流潜在地减少数据点数量的倍数——而不会引入抽样方法中固有的任何统计不准确性。重要的是,DTrace 聚合机制呈线性扩展:信息保存在每个 CPU 的基础上,然后定期在用户级别跨 CPU 聚合。这绝不仅仅是实现细节;用于观察并行系统的工具必须始终比它们试图观察的软件扩展性更好,否则它们自身的瓶颈会掩盖底层系统的可扩展性。如图 3 所示,DTrace 聚合机制允许简洁地回答有关系统的问题。

DTrace 的架构元素——安全和异构的动态仪表化、任意操作和谓词以及可扩展的、原位数据聚合——允许对生产系统进行前所未有的可观察性。然而,在使用 DTrace 时,我们很快遇到了一个棘手的问题:有效地仪表化系统需要了解实现。为了纠正这个缺点,我们引入了提供程序机制,既可以定义其探针的接口稳定性,又可以声明转换器,这些转换器可以将特定于实现的数据结构转换为更抽象、与实现无关的数据结构。这些机制共同允许提供程序通过提供表示子系统语义的探针和参数来从其实现中抽象出来。例如,我们没有要求用户了解在操作系统中执行 I/O 的函数,而是引入了一个 io 提供程序,其探针具有诸如 start 和 done 之类的名称,以及与 I/O 操作相关的与实现无关的参数,例如有关缓冲区、设备、文件等的信息。图 4 显示了使用 I/O 提供程序的示例,包括示例输出。

凭借根据系统语义仪表化系统的能力,一个更大的问题成为焦点:虽然我们可以仪表化用本机编译语言(如 C、C++、Fortran、Objective C 等)编写的应用程序,但我们对用解释型语言或面向虚拟机环境的语言编写的应用程序一无所知。这是一个关键问题,因为抽象堆栈比本机编译语言要高得多:任何声称具有系统可观察性的框架都必须能够深入到更抽象的 Java、Python、Perl、PHP 和 Ruby 等语言中。

仪表化这些环境很困难:无论是解释型还是编译为字节码,系统对于这种环境的程序文本概念几乎没有可见性——更不用说如何仪表化它了。为了允许仪表化这些环境,我们开发了一种用户级提供程序机制,允许导出与环境中语义重要事件相对应的探针。这些事件各不相同,但它们通常包括调用函数或方法、创建对象、执行垃圾回收等。截至撰写本文时,已为 Java、Perl、PHP、Python、Ruby、Tcl 和(我们不是在编造)APL 实现了提供程序。图 5 显示了扩展图 1 中的脚本到 PHP 的示例输出。这些提供程序在很大程度上仍然是原型,但它们在其各自的环境中改进调试能力的程度上是显着的。

经验

在 DTrace 公开可用两年多的时间里,它已在 Sun 内外许多有趣的“捕猎牛”活动中成功使用。一个特别富有成效的狩猎场是 Sun 内部的生产 SunRay 服务器。这是一台 10 CPU、32 GB 内存的机器,大约有 170 个用户,DTrace 被用来发现许多问题(其中最臭名昭著的问题在前面提到的参考文献 2 中进行了广泛讨论)。

关于这个系统的一个常见抱怨是其高 CPU 利用率,这引出了一个自然的问题:哪些应用程序正在消耗 CPU 周期?有几种方法可以使用 DTrace 来回答这个问题;最简单的方法是使用 DTrace profile 提供程序,其探针以均匀(且完全可编程)的间隔触发。这允许一种抽样方法,并且允许人们例如在每个 CPU 上每秒抽样 1,234 次当前正在运行的应用程序

profile-1234hz
{
@[execname] = count();
}

在服务器上运行这样一个脚本大约 30 秒钟,产生了以下输出(左列是应用程序名称,右列是样本数)

mozilla-bin 662

xprop

719
dtmail 886
netscape-bin 1412
nautilus 1438
ps 2523
java 3451
Xsun 6197
netscape 6600

其中大部分输出并不太令人惊讶:考虑到这台机器正在为 170 个用户提供桌面服务,人们会期望看到 X 服务器 (Xsun) 和 Web 浏览器 (netscape) 以及邮件阅读器 (dtmail) 作为 CPU 消耗大户。然而,有一个非常令人惊讶的数据点:第四大 CPU 消耗者是 ps,Unix 命令,用于列出系统中的进程。这是一个管理命令,通常以交互方式执行。难道是很多人出于某种原因在运行 ps 吗?图 6 中的 D 脚本探讨了这个问题,输出结果如图 7 所示。

 

这表明 ps 命令以令人不安的规律性运行。(每次调用几乎需要一秒半才能运行并不太令人惊讶;拥有超过 3,000 个进程,人们会期望完整的进程列表相当耗时。)人们不会期望在正常机器上每隔约 10 秒运行一次 ps 命令。是谁在运行这个?为什么?使用 DTrace 回答这类问题非常简单

proc:::exec /args[0] == “/usr/bin/ps”/ { @[execname, ustack()] = count(); }

这使得能够聚合应用程序名称和用户堆栈回溯。运行上述命令后,发现 ps 的所有调用最终都来自名为 cam 的应用程序,并且都来自名为 SendUsageRec 的函数。

这立即引起了怀疑:Cam 是 Sun 的 IT 部门编写的一个包装程序,旨在跟踪底层应用程序的使用情况;人们不会期望 cam 做太多工作,更不用说启动 ps 命令了。查看图 8 中显示的 SendUsageRec 的源代码,至少揭示了部分问题。

如果您做过很多 Unix 系统编程,那么看到这段代码可能会引起口头惊呼——就像脚趾被踩到或被针扎到一样。这段代码在做什么?答案需要对 cam 包装器进行一些解释。为了跟踪使用情况,cam 获取一个时间戳并启动底层应用程序;稍后,当底层程序退出时,cam 再次获取一个时间戳,取差值,并将总使用时间发送给守护程序。为了处理底层应用程序在机器重启之前没有退出的情况,cam 还会每 30 分钟醒来一次并执行图 8 中的(非常低效的)代码,以确定底层应用程序已经运行了多长时间,并将使用时间发送给守护程序。(这段代码不仅非常低效,而且也非常糟糕:从第 13 列开始剪切不仅包括所需的 TIME 字段,还包括 TTY 字段的最后两个字符。)在可能运行两到三个 cam 包装应用程序的桌面上,这不是问题。然而,在这台服务器上,拥有 170 个用户,每隔 10 秒左右就会有一个用户的 30 分钟到期。

一些粗略的计算表明,在某个时候——可能在 400 个用户左右——服务器将(平均)始终运行一个 ps。不用说,ps 及其在内核中 /proc 文件系统中的基础都不是为了在这种持续使用的情况下设计的。事实上,在发现这个问题之后,系统中几个先前神秘的问题——包括内核进程管理子系统中异常高的锁争用——开始变得更有意义。因此,解决这个问题不仅减少了系统中的 CPU 使用率(从而减少了延迟),而且还提高了可扩展性(从而提高了吞吐量)。

这是使用 DTrace 发现的各种问题的一个很好的例子:这是一个位于抽象堆栈高处的愚蠢问题,并且问题的症状本质上是系统性的。这个问题不可能从单个程序的角度来理解,因为只有当多个相同程序的实例放在一起时,才能看到系统性问题。尽管这个问题可能很愚蠢,但它对系统产生的影响是巨大的。也许最令人沮丧的是,在引入 DTrace 之前,人们已经花费了几个月的时间进行密集(但徒劳)的努力来理解该系统。这不是之前一直在检查系统的优秀人员的失败,而是他们一直使用的迟钝工具的失败——这些工具不允许他们将堆栈底部的症状与顶部的原因联系起来。

未来工作

虽然 DTrace 允许了系统可观察性的新程度,但仍有许多工作要做。例如,虽然我们的用户级提供程序机制允许对动态环境进行一些可见性,但它过于粗粒度:对于与进入方法或函数等高频事件相对应的单个探针,当人们只对仪表化程序的一小部分感兴趣时,启用的探针效应太高。虽然 DTrace 可以仪表化文本点,但它没有真正的方法来记录来自这些环境的数据(甚至参数)。这些问题并非易事;在已解决这些问题的地方(使用字节码仪表化或类似技术),几乎总是使用特定于语言而不是系统通用的解决方案。

除了 DTrace 之外,软件可观察性的新能力还在软件可视化等已建立的领域开辟了新的潜力。特别是,诸如 IBM 的 PV 研究原型 4 之类的有趣的系统可视化工作现在应该可以在生产系统上实现,从而极大地提高其范围和影响。

最后,虽然解决单系统可观察性问题奠定了关键基础,但这只是在更具挑战性的问题上的渐进工作:观察分布式系统。一个潜在有希望的领域是将单系统可观察性基础设施与操作系统级虚拟化技术 5 相结合,以在单台机器的范围内获得分布式调试。虽然前景广阔,但这最终是一个仅限于开发系统的解决方案:观察生产分布式系统仍然是一个开放性问题。该领域中一项值得注意的工作是 Google 的 Sawzall 6,这是一个旨在分析跨多台机器的日志数据的系统。Sawzall 具有过滤器和聚合器,在某些概念上与 DTrace 相似,但不同之处在于它对数据进行后处理,而 DTrace 在原位处理数据。尽管如此,来自 DTrace 和 Sawzall 等系统的想法的汇合可能会在长期存在的分布式系统可观察性问题上取得一些进展。

鉴于 DTrace 的成功,我们预计会出现其他系统可观察性问题的解决方案。为了确保成功,未来的解决方案应遵守相同的约束:绝对安全,生产系统高于一切。遵守此约束——并添加机制以仪表化整个抽象堆栈,从而突出显示模式——允许在最迫切需要可观察性的地方实现新的可观察性:在生产系统中,以及在抽象堆栈的高处。凭借观察运行中的整个抽象堆栈、生产软件的能力,捕猎牛的季节已经开放,并且没有捕猎限额。问

参考文献

  1. FreeBSDTrace 项目; http://www.sitetronics.com/wordpress/
  2. Cantrill, B., Shapiro, M., 和 Leventhal, A. 2004. 生产系统的动态仪表化。2004 年 Usenix 年度技术会议论文集。
  3. Sun Microsystems. 2005. Solaris 动态跟踪指南。
  4. Kimelman, D., Rosenburg, B., 和 Roth, T. 1997. 真实世界软件系统动态性可视化。载于《软件可视化:作为多媒体体验的编程》,MIT 出版社。
  5. Price, D., 和 Tucker, A. 2004. Solaris zones:用于整合商业工作负载的操作系统支持。第 18 届 Usenix LISA 会议论文集。
  6. Pike, R., Dorward, S., Griesemet, R., 和 Quinlan, S. 即将出版。解读数据:使用 Sawzall 进行并行分析。《Scientific Programming Journal》杂志。

BRYAN CANTRILL 是 Sun Microsystems 公司 Solaris 内核开发部门的高级工程师。他的兴趣包括动态软件检测、事后可诊断性以及实时内核和微处理器架构。最近,他(和两位同事)设计、实现并发布了 DTrace,这是一种用于 Solaris 系统动态检测的工具。Cantrill 获得了布朗大学计算机科学专业的 Sc.B. 学位。

acmqueue

最初发表于 Queue 杂志第 4 卷第 1 期
数字图书馆 中评论本文





更多相关文章

David Collier-Brown - 你不了解应用程序性能的真相
当您遇到性能或容量规划问题时,无需进行全面的基准测试。一个简单的测量就能提供您系统的瓶颈点:这个示例程序在每 CPU 每秒处理八个请求后会显著变慢。这通常足以告诉您最重要的事情:您是否会失败。


Peter Ward, Paul Wankadia, Kavita Guliani - 在 Google 重塑后端子集化
后端子集化对于降低成本很有用,甚至对于在系统限制内运行可能是必要的。十多年来,Google 使用确定性子集化作为其默认后端子集化算法,但尽管该算法平衡了每个后端任务的连接数,但确定性子集化具有高水平的连接抖动。我们在 Google 的目标是设计一种具有减少连接抖动的算法,它可以取代确定性子集化作为默认后端子集化算法。


Noor Mubeen - 工作负载频率缩放定律 - 推导与验证
本文介绍了与每个 DVFS 子系统级别的工作负载利用率缩放相关的方程。建立了频率、利用率和比例因子(其本身随频率变化)之间的关系。这些方程的验证结果证明是棘手的,因为工作负载固有的利用率也在治理样本的粒度上以看似未指定的方式变化。因此,应用了一种称为直方图脊迹的新方法。当将 DVFS 视为构建块时,量化缩放影响至关重要。典型应用包括 DVFS 管理器和/或影响系统利用率、功耗和性能的其他层。


Theo Schlossnagle - DevOps 世界中的监控
监控看起来可能非常繁重。最重要的是要记住,完美永远不应成为追求更好的敌人。DevOps 使组织内部能够进行高度迭代的改进。如果您没有监控,那就获取一些;获取任何东西。有总比没有好,如果您已经拥抱了 DevOps,那么您就已经承诺随着时间的推移使其变得更好。





© 保留所有权利。

© . All rights reserved.