对于 zStorage 来讲,影响性能的最主要的几个硬件是:CPU、内存、网络和硬盘。在传统的网络设备和硬盘设备上,一般认为网络和硬盘是主要的性能瓶颈;相反,CPU 和内存的性能相比之下要高出几个数量级,不会成为瓶颈。然而,近年来高速 NVMe SSD 硬盘和高速 RDMA 网卡迅猛发展,其性能提升速度远高于 CPU 和内存。很难想象,网络和硬盘的响应时间已经小于 10 μs 级别,并且网络和硬盘的性能还在不断提升。如果说在 10 ms 级别时,与 CPU 和内存相比存在数量级的性能差异,这没有问题。但是来到 10 μs 级别时,CPU 和内存的耗时已经不可忽视。一次内存访问也在 100 ns 级别,而一次 IO 请求经过的代码路径上可能会访问成百上千次内存,这个耗时不容忽视,甚至已经大于了网络的传输时间,甚至也大于了硬盘的响应时间。
所以,在这种情况下,CPU、内存、网络和硬盘的性能都需要评估。特别是内存、网络和硬盘都可能成为瓶颈。目前来看,CPU 相比内存的性能还是要高出几个数量级。此外,在 CPU 和内存之间还有 L1、L2、L3 这三级缓存
。因此,在做性能分析时,CPU 和内存需要结合起来看。CPU 一般不会成为主要瓶颈,关注点还是在内存的带宽以及 CPU 缓存的命中率上。当内存通道较少(内存条数量不足)或者跨 NUMA 节点访问内存时,内存可能成为瓶颈;当网卡降级,或者网卡带宽较低时,网卡可能成为瓶颈;当硬盘的带宽或 IOPS 数据较差,或者硬盘数量较少时,硬盘可能成为瓶颈。
同样的道理,可以分析出性能瓶颈是否在网络上。如果我们排除了硬盘和网络的瓶颈,剩下的就只有 CPU 和内存了。要确认是否是 CPU 和内存的瓶颈,我会找两个点位,这两个点位之间只有执行代码流程,没有网络、硬盘、系统调用
、锁、sleep 等操作。
以下图这样一个简单的模型来说明问题:整个黑色曲线
是一个 IO 路径的全部耗时,其中 B0 到 B1 是模块 B 的耗时,A0 到 A1 是模块 A 的耗时,而模块 A 的耗时包含了模块 B 的耗时。真正属于模块 A 的消耗时间为 A0B0 + A1B1 = TA。
由于 TA 是纯粹的代码耗时,这个耗时与 CPU 和内存的性能强相关。如果 TA 的耗时为 100 μs,远大于硬盘的耗时 40 μs,那么可以认为 CPU 或内存存在瓶颈。我在一个实际的现场项目中,曾以这种方式定位过一个问题,最后发现是因为内存条数量不满足要求。实际只安装了一根内存条,而配置清单上写的是 8 根。因此,当时没有先实际检查硬件配置,而是通过这样的时延分析方法,确定了问题方向为内存。
perf工具
另一个高频应用于性能分析的工具是
perf
。perf 工具可以细致地分析各个函数的 CPU 占比、缓存未命中百分比、分支预测失败百分比,以及 IPC(每个时钟周期
执行的指令数)等性能指标。