What is performance?

Salvatore Sanfilippo

什么是性能?

原文由 Salvatore Sanfilippo 发布,订阅该博客

这篇博文的标题看似是个不言自明的问题,但值得更深入地思考性能究竟意味着什么:人们很容易混淆可扩展性与性能,而在数据库系统这一特定场景下,将性能拆解为几个主要组成部分,也并非易事。在这篇短文中,我想谈谈自己目前对数据库系统语境下“性能”这一概念的理解。

一个不错的切入点,或许是我最近在介绍 Redis 的演讲中用到的第一张幻灯片。这张幻灯片讲的正是性能,它指出性能主要包含三个方面。

  1. 延迟:完成一次查询并收到回复所需的时间。
  2. 单位时间单位核心的操作数:在给定的基准计算单元上,系统每秒能响应多少次查询(操作)?
  3. 操作质量:这些操作能完成多少有效工作?

延迟

这或许是性能中最容易理解的一个维度。在许多应用中,我们都希望从系统获得响应的时间越短越好。不过,除了平均耗时很重要之外,延迟的可预测性以及平均情况与最坏情况之间的差距,也同样值得关注。如果使用得当,内存系统能够提供非常出色的延迟表现,并且能在长时间内保持延迟的稳定。

每核每秒操作数

我列出的第二个维度,正是区分原始性能与可扩展性的关键。我们关心的是,在给定的基准计算单元上,系统在单位时间内能完成多少工作。可线性扩展的系统可以通过增加节点数量来达到很高的每秒操作数,但这只说明它们具备可扩展性,并不一定意味着性能出色。

每核每秒操作数通常也与每瓦特能执行的查询数量直接相关,也就是系统的能效。

操作质量

最后一点虽然在开发者中不像吞吐量和延迟那样常被强调,但在某些类型的系统中却至关重要,尤其是在内存系统中。

一个每秒能执行 100 次操作,但操作“质量不高”(比如按 Redis 的说法,只有 GET 和 SET)的系统,与一个在相同延迟和 OPS 条件下还能执行 INCR 操作的系统相比,性能要更低。例如,如果当前要解决的问题是递增计数器,前一个系统需要两次操作才能完成一次递增(这里暂不考虑竞态条件),而支持 INCR 的系统只需一次操作就能完成。因此,后者的实际性能其实是前者的两倍。

可以看到,操作质量并不是一个绝对的衡量标准,而是取决于要解决的具体问题。如果我们只是想缓存 HTML 片段,那么上面提到的两个系统就是等价的,因为 INCR 操作在这种场景下毫无用处。

操作质量在内存系统中尤为重要,因为通常情况下,计算本身的开销与接收、分发命令以及生成回复所需的时间相比可以忽略不计,因此像 Redis 这样拥有丰富操作集合的系统,能够在许多场景下几乎不增加额外成本地提供更好的性能——仅仅是让用户通过单次操作就能完成更多工作。这里的“做更多”可以有很多含义:既可以是对更复杂问题的直接回答,例如 Redis 的 ZRANK 命令,也可以是提供更具选择性的回复,例如 HMGET 命令,它能够只返回构成 Hash 值的部分字段的信息,从而减少服务器与客户端之间所需的带宽。

一般来说,操作质量之所以影响性能,并不仅仅是因为它让系统每秒能执行的操作数变得更有或更没有价值:操作质量还会直接影响延迟,因为更复杂的操作能够避免为了将多个简单操作组合成一个复杂计算而在客户端与服务器之间来回传输数据。

结论

希望这篇关于“什么是性能”的简短探讨,能够揭示从这一特定视角评估数据库系统能力时所涉及的一些复杂性。关于这个话题还有很多可说的,但在我看来,上述性能的三个组成部分,是在评估一个系统以及思考如何改进现有系统以提升其性能特征时,最有意思、也最重要的几个维度。

感谢 Yiftach Shoolman 就这一话题提供的反馈。

本文章由 muse-spark-1.2-contributor 进行翻译

评论