1.5 性能是充满挑战的
系统性能工程是一个充满挑战的领域,具体原因有很多,其中包括以下事实,系统性能是主观的、复杂的,而且常常是多问题并存的。
1.5.1 性能是主观的
技术学科往往是客观的,太多的业界人士审视问题非黑即白。在进行软件故障查找的时候,判断bug 是否存在或bug 是否修复就是这样。bug 的出现总是伴随着错误信息,错误信息通常容易解读,进而你就明白错误为什么会出现了。
与此不同,性能常常是主观性的。开始着手性能问题的时候,对问题是否存在的判断都有可能是模糊的,在问题被修复的时候也同样,被一个用户认为是“不好”的性能,另一个用户可能认为是“好”的。
考虑下面的信息:
磁盘的平均I/O 响应时间是1ms。
这是“好”还是“坏”?响应时间或者说是延时,虽然作为最好的衡量指标之一,但还是难以用来说明延时的情况。从某种程度上说,一个给定指标是“好”或“坏”取决于应用开发人员和最终用户的性能预期。
通过定义清晰的目标,诸如目标平均响应时间,或者对落进一定响应延时范围内的请求统计其百分比,可以把主观的性能变得客观化。第2章将介绍处理这类主观性的方法,其中就有通过统计操作延时的比例来进行延时分析的方法。
1.5.2 系统是复杂的
除了主观性之外,性能工程作为一门充满了挑战的学科,除了因为系统的复杂性,还因为对于性能,我们常常缺少一个明确的分析起点。有时我们只是从猜测开始,比如,责怪网络,而性能分析必须对这是不是一个正确的方向做出判断。
性能问题可能出在子系统之间复杂的互联上,即便这些子系统隔离时表现得都很好。也可能由于连锁故障(cascading failure)出现性能问题,这指的是一个出现故障的组件会导致其他组件产生性能问题。要理解这些产生的问题,你必须理清组件之间的关系,还要了解它们是怎样协作的。
瓶颈往往是复杂的,还会以意想不到的方式互相联系。修复了一个问题可能只是把瓶颈推向了系统里的其他地方,导致系统的整体性能并没有得到期望的提升。
除了系统的复杂性之外,生产环境负载的复杂特性也可能会导致性能问题。在实验室环境很难重现这类情况,或者只能间歇式地重现。
解决复杂的性能问题常常需要全局性的方法。整个系统——包括自身内部和外部的交互——都可能需要被调查研究。这项工作要求有非常广泛的技能,一般不太可能集中在一人身上,这促使性能工程成为一门多变的并且充满智力挑战的工作。
如同第2章要介绍的内容一样,多样的方法可以带我们穿越这些复杂性的重重迷雾。第6~10章讲的是针对特定系统资源的方法,这些系统资源包括CPU、内存、文件系统、磁盘和网络。
1.5.3 可能有多个问题并存
找到一个性能问题点往往并不是问题本身,在复杂的软件中通常会有多个问题。为了证明这一点,试着找到你的操作系统或应用程序的bug 数据库,然后搜索性能performance 一词,对于结果你多半会很吃惊!一般情况下,成熟的软件,即便是那些被认为拥有高性能的软件,也会有不少已知的但仍未被修复的性能问题。这就造成了性能分析的又一个难点:真正的任务不是寻找问题,而是辨别问题或者说是辨别哪些问题是最重要的。
要做到这一点,性能分析必须量化(quantify)问题的重要程度。某些性能问题可能并不适用于你的工作负载或者只在非常小的程度上适用。理想情况下,你不仅要量化问题,还要估计每个问题修复后能带来的增速。当管理层审查工程或运维资源的开销缘由时,这类信息尤其有用。
有一个指标非常适合用来量化性能,那就是延时(latency)。