你的问题是什么?
好,现在咱们聊聊真实的生活。一个关键的服务器上有些(或是全部)应用很慢,没人知道怎么回事,你—要来解决这个问题。现在…你很牛,非常牛,你已经收集了一些历史数据;而且你也很清楚系统正常运行的时候是什么样子;有人经常观察系统资源的利用率,像CPU、内存、网络、核心table啥的;Performance Agent工作得很正常,24X7地收集了数据。除了本地访问这些数据,你还可以通过Openview家族的Performance Manager、Operation Manager远程观察PA的数据。而且,HP Capacity Advisor可以对这些数据进行处理。不管用什么工具,重要的是理解基线,因为东西出了差错以后你可以什么资源异常。如果你很土,非常土,或者就是命苦,你完全不知道正常时是什么样子,那你只能胡乱划拉:找出工具显示出的最可能的瓶颈,希望你努力的方向是正确的。从上(系统级)至下看哪些资源忙再钻下去。
理解应用程序的结构,它如何使用资源是非常有帮助的。例如,你知道系统是一个专用的数据库服务器,而且主要的数据库都存放在裸设备上,那你就不用浪费时间去调文件系统的参数或是buffer cache还是UFC什么的,对于祼设备来说这些不相关。如果你通过Glance和PA的parm文件把应用程序的重要进程都封装到一个包,你就可以对比相关的应用程序资源使用情况,有希望找到故障相关的这组进程。通常繁忙的服务器上有非常多的活跃进程,所以你需要深入了解性能问题来判断哪个进程需要进一步研究。
如果一个应用程序或是进程运行不了,或是运行一段时间后退出,那么你可能面临的不是一个性能的问题,可能是某个阀值被突破了,常见的可能是设得太小的核心参数,但最可能的是应用程序的参数设定(例如Java的设置),或是交换区空间的问题。通常查询HPUX或是应用程序的文档会告诉你哪些参数要增大。Glance的System Tables报告也有帮助。另外,确保已经安装了最新的patch bundle. 如果没有出错的部分,但是运行的就是慢,那么事情就变得有意思了!
资源瓶颈
对系统资源来说充分的使用并不是坏事,毕竟这都是花钱买的!高的资源利用率和瓶颈不能画等号。所谓的瓶颈,现象是某个资源被完全占用了,而且有一系列的进程或是线程等着用这个资源。进程等待资源时运行得比正常时就会慢些。
一般的瓶颈特征如下:
- 某个资源被使用,而且
- 进程或线程在等待使用这个资源
从下一章节开始,我们开始对具体类型的瓶颈进行研究。当然,我们没办法罗列所有可能的类型,但是我们会尝试覆盖最常见的。讨论每种类型的瓶颈的开始部分,我们会列出几个主要的现象(黄按,原文用词‘作料’),如果有必要,就再分析得详细一点。你可以快速地扫描一下这些’作料’与你遇到的有多吻合。就像电视上常说的(那就应该是对的),所有好菜从好作料开始!除非你是Stephen(超级牛厨),有一套自己的作料。
想更好地理解瓶颈的形成,考虑这样一个备份的例子。备份的过程包括从磁盘读取数据和写入到备份设备(如另一硬盘、磁带机或是通过网络). 整个备份过程不可能无限快,会因为某些资源受到限制。数据流中最慢的资源可能是读取数据的硬盘(表现为源数据盘接近100%繁忙),也可能是备份输出的设备。备份还可能会受限于CPU的速度(可能在使用压缩算法时,指示为进程占用CPU100%时间)。你可以通过为受限的资源增加速度来加速整个备份过程,但是如果备份在你期望的时间段内完成,也没有影响到其他任何的任务,那就没有问题!让备份运行得更快不是最好的使用时间的方法。记住:一个硬盘(或其他的什么)100%忙不必然预示着存在瓶颈。当伴随着长的队列(queue),或者还有平均响应时间的增加等,这就有可能说明有问题。
如果,你的备份任务在工作时间服务器开始繁忙之前还没有结束,你可能会发现备份进行时很多程序慢得像老牛破车,这是因为应有程序之间在竞争与备份任务相同的资源.这时候你就真的有一个性能瓶颈了!一个最常见的性能问题场景就是备份任务运行得太久以至于影响到了日常的业务。通常最简单的‘优化’就是调整哪些内容需要备份,来保证性能与数据完整性的平衡。
如果开始性能分析时已经知道哪些应用程序和进程运行得比平时慢,那就看这些特定的进程在等待什么资源。有时候不像说起来这么简单,因为UNIX对指示在等待什么资源并不是很在行。Glance 和PA(也叫Measureware)中有这样一个概念叫Blocked States(受限状态,等待原因)。你可以在Glance中选中一个进程,进入Wait States页面可以看到百分之多少的时间被用来等待不同的资源。不幸的是,这通常不能直接告诉你问题的所在。有一些,比如说Priority,比较明显。如果一个进程因为在Priority受限(blocked),那就说明它在更高优先级的进程运行时需要等待CPU时间。有些其他的原因,比如说Streams(streams IO子系统)就麻烦一些了。如果一个进程大部分时间受阻于Streams,那可能是因为网络瓶颈,但更可能的是,它在从Stream设备上等待某个输入。例如shell程序会在Stream端等待终端上的输入。
Metrics(测量指标)
我们关注的是性能,不是性能指标。我们需要在分析问题的时候讨论不同的指标,但是我们不会具体研究指标是如何定义的,是怎么得出来的这些内容。如果你安装了Glance,运行xglance(和gpm是一样的),点击Help -> User’s Guide ,然后点击Performance Metrics部分,可以看到所有的定义。另外,你可以在xglance中的某一个report窗口中点击Configure->Choose Metrics, 列出来这部分可选择的Metrics, 你还可以点击右键调出相应的定义说明。
如果你安装是PA(measureware),在/opt/paperdocs/ovpa/C/methp*.txt是相关定义的文档。在文本界面运行glance可以看到部分metrics, PA也是这样。需要工具与metrics更多信息,查找下面References部分的链接。
我们用了很多‘进程’这个词,但是在HPUX里实际上指的是可以单独运行的一个单元,也就是线程。一个进程是可以有多个线程的。一个有10个线程的进程可以完全消耗10个CPU(每个线程100%占用一个CPU,父进程使用’1000%’CPU – 注意process metrics不考虑CPU个数). 这和10个单线程的进程,每个100%占用一个 CPU是类似的。
要记住,metrics不是完美的。任何性能工具提供给你的不管精确到多少位的数字基本上都是有偏差的!这里面的原因涉及到采样、标准化、压缩、同步等多方面。重要的是,不要盲目相信任何工具与metric. 总得来说,metric通常是有用的、准确的,但是数据会有些偏差。就像下面在内存瓶颈部分的例子。或是问下Stephen为什么这个世界上他最讨厌的数字是327.67(黄按:这句话真没搞懂是啥意思)。
CPU Bottlenecks (CPU瓶颈)
CPU瓶颈现象的作料(故障现象):
-持续的高CPU占用率 (GBL_CPU_TOTAL_UTIL > 90%)
- 运行队列值偏大(Significant Run Queue,即指平均负载) 或是进程持续因为Priority受阻( blocked on Priority) (GBL_RUN_QUEUE > 3 or GBL_PRI_QUEUE > 3).
- 重要进程经常显示为等待CPU ( blocked on Priority )(PROC_STOP_REASON = PRI).
判断是否存在CPU瓶颈很简单。总的CPU利用率(平均到所有CPU)的值接近100%, 总有进程在等待运行。找出为什么CPU瓶颈发生有时不那么容易。所以了解系统正常运行时的基线很重要,你可以比较容易地找出引起问题的程序。Stephen喜欢把这些称为‘犯规’程序。
Priority Queue metric(从进程受阻状态process-blocked states得来),显示了平均有多少个进程在等待任一个CPU(也就是受阻于priority),这个系统中有多少CPU没什么关系。Stephen比喜欢用Run Queue更喜欢这个。Run Queue是平均在每个CPU上有多少个可运行的进程。它的效果和运行top或是uptime命令中的Load Average metric(平均负载)基本上是一样的。不同的性能工具或是使用平均值,或是截取瞬间值。
我们也要提一下你可能在别的什么文档中看到过其他的经验法则,有什么你觉得更好用的方法欢迎告诉我们。我们的法则多年来已经被很多管理员验证过。
要分析CPU瓶颈,首先要看大部分的CPU时间是在系统模式(System or Kernel mode),还是用户模式(User mode,outside kernel),按你的情况跳到下面相应的子章节。
User CPU Bottlenecks (用户模式CPU瓶颈)
问题现象:
- 如上面所述的CPU瓶颈的现象,并且
- 大部分CPU时间花在用户代码上 (GBL_CPU_USER_MODE_UTIL > 50%).
如果你的系统大部分时间在执行核心以外的代码,通常是件好事。你只需要确认正在执行’正确的’代码. 找到用CPU最多的进程(在Glance中以PROC_CPU_TOTAL_UTIL排序)看真正占用CPU的进程是不是你希望的那些。在Glance中,你可以选中一个进程进一步获取详细信息。如果一个进程全部的时间都在User Mode,没有做任何的系统调用(System call),并且没有IO操作,那它可能是被卡在自旋(spin). User mode进程产生IO操作时可能在做内存映射IO(memory-mapped I/O ).如果shell进程(sh,ksh,或csh)在耗CPU,和用户确认一下是不是卡住了(有时网络中断会造成Shell在循环中卡住)。
如果是‘错’的应用程序占用了全部CPU时间,表现为重要的进程总是因Priority被Block。有几个工具可以用来做更深入的分析,包括安腾平台的’Caliper’.对Oracle环境,Statspack是有用的工具,跟你的数据库管理员聊聊。
HP PRM工具(Process Resource Manager)和gWLM(Global Work Load Manager)可以检查每个应用对CPU的使用。 有些应用通过逻辑隔离能有些好处,工具有nPars,vPars和HPVM. 如果是合并作业(consolidation activities),HP Capacity Adviser可能有用。系统不断变化,有时候就是需要找到最合用的工具。
一个短期的解决办法可以是适当地使用renice命令。 你在Glance中选中一个进程也可以调用。增加nice的值会降低它的优先级。有很多调度任务的技巧,包括POSIX scheduler, 尽管这不常用。Oracle建议禁止用户级别的时间片优先级调低的操作(通过设置SCHED_NOAGE核心参数). 这个有点复杂,Stephen可以就这个开一个两天的研讨会。简单的(也是正确的)解释是,很多人用“优先级反转”这个术语来讨论。如果你设置了SCHED_NOAGE,它就告诉核心不要降低一个进程或是线程的优先级。通过rtsched命令或是系统计调用能使用的最适当的优先级是178.
最简单的解决CPU瓶颈的方法是买更强的CPU处理能力。通常来讲,更多、更强、更快的CPU会让程序运行更快。另一个方式是应用程序的优化,如果有源代码的话有很多编程工具可以用。下面参考引用部分的HP Developer and Solution Partner门户是一个好地方来寻找相关的工具。
System CPU Bottlenecks (系统模式CPU瓶颈)
现象:
- 如上所述的CPU瓶颈现象, 并且…
- 大部分时间用在kernel (GBL_CPU_SYS_MODE_UTIL > 50%).
如果大部分CPU时间用在系统模式,就需要进一步细分那些操作使用了这么多的时间。首先,检查是否大部分消耗在上下文切换(context switching). 这本身就是一个专题,如果是的话直接跳到下面的上下文切换瓶颈的相关部分。
如果不是因为上下文切换,那观察GBL_CPU_INTERRUPT_UTIL 是否大于 30%,如果是,你更可能遇到的是IO瓶颈(就是说,你看到的CPU瓶颈是由IO瓶颈造成的),或者是你的IO卡有些问题。先研究IO相关的问题。内存瓶颈也有可能伪装为CPU瓶颈:如果内存完全使用了伴随着paging,先看看内存的瓶颈问题。
有人和我们聊过vPars中关于绑定或是非绑定CPU(bound,unbound)的问题,只有绑定的CPU处理IO中断。在实际应用环境我们没发现这有什么大问题。换句话说,如果你不是要处理海量的IO,而且你观察到很高的中断处理量,不用担心绑定CPU的数量是否足够。
要是你的高CPU占用率不是因为上下文切换,那我们基本上可以认为大部分时间是用于处理系统调用(System call).(GBL_CPU_SYSCALL_UTIL >30%). 这就要看一下具体是哪种系统调用了。
如果问题出现时你能使用Glance是最好的,你可以去买张彩票跳到下一段。如果只能看历史数据或是只有其他工具,没有具体的系统调用分解,就需要根据其他的Metrics分析。查看性能有问题时段哪个进程系统调用最高
(highest PROC_CPU_SYSCALL_UTIL) 看它的其他指标或是根据它的行为看能不能找到系统调用过高的原因。如果这问题正在发生,那就用Glance再进入一点看。我们推荐用gpm(xglance),因为排序与metric选择更方便。选择 Reports->System Info->System Calls, 在界面中以syscall rate排序. 最经常被调用的system call会排在最前面。还可以以CPU time排序,看哪个系统调用占用最多的时间,因为有些系统调用耗费的时间明显多些。在xglance的Process List报告中,可以选择PROC_CPU_SYS_MODE_UTIL,在核心里使用最多时间的进程会排在前面.选中一个进程,点击Process System Call report,等一段时间后(等几个glance更新数据的时间间隔),就可以看到进程正在使用的系统调用。要记住不是所有系统调用直接对应libc的接口,可能需要些对核心的理解,把系统调用与源代码对应起来。当你了解了是哪些进程造成了瓶颈,它们在执行什么操作,剩下的难点就是判断为啥了,我们留给用户作为练习!
常见的编程错误就像重复的gettimeofday(), sched_yield(),
或是 select() (我们比较烂的程序见过每秒调用数千次的),可能是系统模式CPU瓶颈的根本原因。另一个常见的原因是过多的stat类型文件系统类的系统调用(find命令就容易造成类似的调用,shell配置了过长的PATH变量也有可能)。我们曾经追踪到一个case是因为在循环对/dev/null文件做打开和关闭的操作!
我们曾经见过一个case,程序之前以非常小的读、写操作通讯。这样的操作带来的副作用就是产生很多核心系统调用来跟踪,从而使midaemon(Glance和PA使用)进程使用大量的CPU时间。所以,如果你见到midaemon进程使用很多CPU,查找除midaemon进程之外大量使用CPU的进程(就像上面说的,把进程以PROC_CPU_SYS_MODE_UTIL排序). 有些效率不高的程序会产生很短、但是持续不断的系统调用。
在繁忙的大型系统计上,系统模式CPU瓶颈可以是核心资源的竞争,比如说数据结构一次只能由一个CPU访问。你可能听说过自旋锁(spinlock),就是CPU要等待虚拟内存或是IO控制数据结构解锁。这种情况会造成很长时间的系统调用。在工具里这显示为系统模式的CPU时间,很难和其他情况区分开来。通常来讲,这是OK的因为从一个系统管理员的角度你对这也没什么办法。做很多文件操作的程序更容易有竞争。如果程序不做系统调用,那它就不会被kernel拖慢下来,遗憾的是不总是能做到。
有一个系统跟踪工具叫tusc,它对分析特定进程生成的系统调用非常有用。(黄按:晚点我贴一个tusc的文件上来).我们得说有些应用程序被设计成生成无穷多的系统调用,但是没有太多的办法,尤其是对第三方开发的程序。我们也见过开发者为了性能选择不恰当的系统调用。这个就复杂喽,一瓶啤酒还不够Stephen讲的。
阅读(1488) | 评论(0) | 转发(0) |