摘要
性能追踪建议
没有远见和规划,这样解决性能问题是痛苦的。产生问题的原因一次又一次从指尖溜走,不仅浪费时间并且让你备感受挫。但是,如果按照正确的步骤,就可以把令人沮丧的性能追踪转变为有趣的侦探故事。每一条信息都让你更接近问题的根源。人不可能总是可信的,证据将是你唯一的朋友。当你开始研究问题的时候,会遇到不寻常的波折,追踪之初发现的信息最后可能会帮你解决问题。最棒的部分就是,当你最终逮住“坏小子”并修复问题时,会感觉到肾上腺素的刺激和成就感。
如果你从来没有调查过性能问题,那么第一步会是决定性的。不过,听从下面几个明显或隐晦的建议,可以节约时间,并按照自己的方式来找出性能问题的原因。本章目标是提供一系列建议和指导来帮助读者追踪性能问题。在研究系统或应用程序出现的问题时,这些建议告诉你怎样避开一些常见的陷阱。这些建议,大多数都是从浪费的时间和令人沮丧的死胡同中辛苦得到的教训,它们有助于快速并有效地解决你的性能问题。
阅读本章后,你将能够:
避免重复他人的工作。
避免重复自己的工作。
避免因收集的误导信息而导致的虚假线索。
为你的研究创建有用的参考文档。
尽管所有的性能调查都是有瑕疵的(“如果一开始就能想到”是你的口头禅),但这些建议将会帮助你避免性能研究中的一些常见错误。
1.1 常用建议
1.1.1 记大量的笔记(记录所有的事情)
在调查性能问题时,你可以做的最重要的事情大概就是记录下看到的每一个输出、执行的每一条命令,以及研究的每一个信息。结构清晰的记录能让你只查看记录就可以检验关于性能问题原因的猜想,而不是重新运行测试。这能节约大量时间。写下来并且创建性能记录。
在性能调查之初,我通常会为其创建一个目录,在GNU Emacs中打开一个新的“Notes”文件,开始记录系统的信息。之后,将性能结果保存到这个目录,并将有意思的和相关的信息保存到Notes文件。建议将下面的内容添加到你的性能调查文件和目录中:
记录硬/软件的配置情况—记录下的信息包括硬件配置(主存容量、CPU类型、网络和磁盘子系统)和软件环境(OS和软件的版本、相关配置文件)。这些信息看上去很容易在之后重现,但是在追踪问题时,你可能会大幅度地修改系统配置。认真细致的笔记有助于在特定的测试过程中弄清楚系统配置。
示例:每次测试时,保存cat /proc/pci、dmesg和uname -a的输出。
保存并组织性能结果—运行很长时间后还能评估性能结果是很有价值的。记录系统配置的同时,也记录测试结果。这使你得以比较不同的配置是如何影响性能结果的。如果需要,可以重新运行测试,但是测试一种配置是耗费时间的过程。只需让笔记保持条理清晰,避免重复工作则效率更高。
写下命令行调用—在运行性能工具时,常常需要用困难复杂的命令行来准确定位到你感兴趣的系统区域进行测量。如果想重新测试,或在不同的应用程序上运行相同的测试,那么,复制这些命令行不仅令人厌烦,并且在初次尝试时,不容易做对。更好的办法是准确记录下你键入的信息。这样在之后的测试中就能够完全重现命令行,而在回顾之前测试结果时,也可以看到你测量的内容。Linux命令script(详见第8章)或者从终端“剪切粘贴”都是完成这项工作的好方法。
记录研究信息和URL—调查性能问题时,将在互联网上发现的相关信息记录下来是很重要的,不论发现的途径是电子邮件,还是人际交往。如果你找到一个看上去相关的网站,就把它剪切粘贴到你的笔记中。(网站是会消失的。)当然,还要记录下URL,因为你可能在之后还要查看这个网页,或者网页所指信息对后面的调查会变得重要起来。
在收集和记录所有这些信息时,你可能会疑惑:这样做值得吗?有些信息眼下显得毫无作用或有误导性,但它在将来可能是有用的。(好的性能调查就像一部优秀的侦探剧:尽管开始的时候所有的线索都令人迷惑,但最终都会真相大白。)在调查问题时,请牢记以下几点:
结果的含义可能是不明确的—性能工具给你的信息并不总是清晰明了的。有的时候,你需要更多的信息才能理解某个结果的含义。之后,你可以回过头以新的视角重新审视那些看似无用的测试结果。实际上,旧信息可能会驳斥或者证明关于性能问题本质的某个特定理论。
所有的信息都是有用的(这也就是你要记录的原因)—记录已运行的测试信息以及系统配置信息的原因不见得会立即明晰。这一点在你试图向开发人员或管理人员解释系统性能不佳的原因时是非常有用的。通过记录和整理调查过程中你所见的一切,你就有证据支持特定理论,同时也具备大量的测试结果来证明或驳斥其他理论。
定期回顾你的笔记可以得到新的想法—当你为性能问题积攒了大量的信息时,那就定期回顾它们。重新审视会让你关注结果,而不是测试。当许多测试结果放在一起被同时查看时,问题的原因也许就会自动浮现。回顾你收集的数据,就可以在不实际运行任何测试的情况下进行理论检验。
在调查问题时,重做一些工作虽然是不可避免的,但是,在重做工作上花费的时间越少,你的效率就越高。如果你写了大量的笔记,并有办法在发现信息时记录它们,那么你就可以依赖已经做过的工作,而避免重复运行测试以及重复研究。保持笔记的可靠性和一致性,从而节省时间减少挫折。
例如,在调查性能问题后,最终确定为硬件原因(主存慢、CPU慢等),你可能会想通过升级慢速硬件,并重新运行测试来检验这个想法。通常要花一点时间才能获得新硬件,而在你可以重新运行测试之前可能已经过了很久。当最终可以开始的时候,你想要在新老硬件上运行同样的测试。如果你已经保存了之前的测试调用和测试结果,那么,你马上就知道要怎样为新硬件进行测试设置,同时也可以比较新的结果与保存的旧结果。
1.1.2 自动执行重复任务
当开始调整系统改进性能时,键入复杂命令行很容易出现错误,而无意中使用的不正确参数和配置则会产生误导性的性能信息。因此,自动执行性能工具调用和应用程序测试是一个好办法:
性能工具调用—有些Linux性能工具的命令行相当复杂,给自己省点力,把它们保存到一个shell脚本中,或是将所有命令都放到可以进行剪切粘贴的参考文件中。这可以让你少受些挫折,并且让你多少有些信心:用来调用工具的命令行是正确的。
应用程序测试—大部分应用程序有着复杂的配置,要么通过命令行,要么通过配置文件。你会经常重新运行要多次测试的应用程序,若将调用保存为脚本,就能少走弯路。虽然刚开始的时候,键入30个字符的命令看上去很容易,但这样的操作重复10次后,你就会向往自动执行了。
尽可能多地自动执行,就能减少错误。使用脚本自动执行,可以节省时间,并有助于避免因不当工具和测试调用造成的误导性信息。
举个例子,你想在特定工作负载下或某段时间内监控系统,但是在测试结束时,你可能不在现场。这种情况下,脚本就很好用了,在测试完成时,可以自动收集、命名、保存全部生成的性能数据,并将它们自动放到“Results”目录中。有了这些基础之后,你就能按照不同的优化和调整重新运行测试,并且不用担心数据是否已经保存好。你反而可以集中精力找出问题的原因,而不是去管理测试结果。
1.1.3 尽可能选择低开销工具
一般情况下,观察系统会修改系统的行为。(对物理爱好者来说,这就是海森堡(Heisenberg)不确定性原理。)
具体而言,在使用性能工具时,它们会改变系统的行为方式。调查问题的时候,你想要看看应用程序是如何执行的,同时还必须处理性能工具引发的错误。这是不可避免的弊端,但是你要知道它的存在,并努力将其最小化。有些性能工具能够给出高度精确的系统信息,但其检索信息的开销也很高。高开销工具对系统行为带来的变化大于低开销工具。如果你只需要了解系统的粗略信息,那么使用低开销的工具是更好的选择,即使它们不够准确。
例如,对于正在使用的应用程序,工具ps能给出其主存数量和类型的相当不错但粗糙的概况。那些准确性更高,但是影响较大的工具,如memprof或valgrind,虽然也能提供这些信息,但是它们消耗的主存和CPU资源比只使用原始应用程序要大,因此会改变系统行为。
1.1.4 使用多个工具来搞清楚问题
虽然在找出性能问题原因的时候,如果只需要用一个工具那将是非常方便的,但这种情况相当少见。实际上,你使用的每一种工具都会为问题的原因提供线索,因此,你必须同时使用多个工具来真正搞清楚发生了什么。比如,一种性能工具会告诉你系统存在大量的磁盘I/O,而另一种工具则告诉你系统使用了大量的交换。如果只以第一个工具的结论制定解决方案,你可能会简单地选择更快的磁盘驱动器(然后发现性能问题仅仅改善了一点点)。而将两种工具的结果放在一起,你就会判断出:大量的磁盘I/O是由大量使用的交换造成的。在这种情况下,你可能会买更多的主存以减少交换(这样就不会再有大量的磁盘I/O)。
比起单一地使用任何一种工具,同时使用多个性能工具通常能让你对性能问题有更清晰的了解。
寓言:盲人摸象
三个盲人在一头大象旁边,想要搞清楚它长什么样子。第一个人拉住了尾巴,说道:“大象就像一根绳子。”第二个人摸到了象腿,说道:“大象像一棵树。”第三个人摸到了大象一侧的身体,说道:“大象像一堵厚实的墙。”
显然,没有一个人得出了正确的答案。如果他们将各自的印象进行共享和组合,那么,他们就可能发现大象真正的模样。别做摸象的盲人。同时使用多种性能工具找出问题的原因。
1.1.5 相信你的工具
性能追踪的过程中,最令人兴奋又令人沮丧的时刻之一,就是工具显示了一个“不可能”的结果。某些“不会”发生的事情却明明白白地发生了。第一反应会认为工具坏了。不要被直觉愚弄了,工具是公正的。虽然它们可能会不正确,但这更有可能是因为应用程序做了不该做的事情。要使用工具来调查问题。
举个例子,Gnome计算器使用超过2000个系统调用只为了实现加载和退出。如果没有性能工具来证明这个事实,那么,仅仅为了启动和停止应用程序就需要如此之多的系统调用看上去是没有必要的。但是性能工具能够显示其发生的位置和原因。
1.1.6 利用其他人的经验(慎重)
在调查任何一个性能问题时,你可能会发现问题令人不知所措。不要独自面对它。问问开发者是否见过同样的问题。试着找到其他解决过你所遇问题的人。在互联网上搜索类似的问题,并希望找到解决方案。给用户和开发人员发电子邮件。
本条建议附带一个提醒:即使开发者认为了解自己的应用程序,他们也不见得总是对的。如果开发者不认同性能工具的数据,那么,他们也许是错的。向开发者展示你的数据以及你为何会得出这样的结论。他们通常会帮你重新解释数据或者解决问题。不论是哪种情况,都会将你的调查向前推进一些。如果你的数据表明发生了不该发生的事情,就不要害怕与开发者有分歧。
比如,你通常可以按照在Google上搜索类似问题得到的指导来解决性能问题。很多时候,在调查一个Linux问题时,你会发现之前已经有人遇到过了(即使是几年前),而且还在公共邮件列表中报告了解决方法。使用Google是很容易的,它可以为你节省几天的工作量。