常用性能数字

简介: 【8月更文挑战第15天】常用性能数字

一、前言

对于性能工程师来说,常见系统的性能数据量级需要烂熟于心,记住这些数字的好处是,每次看到一个性能相关的数据的时候,我们立刻就能知道这个性能数据有没有问题。

举个简单例子,如果我们看到一个硬盘的 IO 读写延迟经常在 500 毫秒左右,我们立刻就知道这里面有性能问题。反之,如果硬盘 IO 读写延迟小于 1 毫秒,我们可以马上推断——这些 IO 读写并没有到达硬盘那里,是被操作系统缓存挡住了。这就是大家常说的“对数字有感觉”。

二、存储硬件

存储有很多种,常用的是传统硬盘(HDD,)和固态硬盘(SSD),SSD 的种类很多,按照技术来说有单层(SLC)和多层(MLC,TLC 等)。按照质量和性能来分,有企业级和普通级。根据安装的接口和协议来分,有 SAS、SATA、PCIe 和 NVMe 等。

对所有的存储来说,有三个基本的性能指标。

  • IO 读写延迟。一般是用 4KB 大小的 IO 做基准来测试;
  • IO 带宽,一般是针对比较大的 IO 而言;
  • IOPS,就是每秒钟可以读写多少个小的随机 IO。
    image.png

SSD 的随机 IO 延迟比传统硬盘快百倍以上,IO 带宽也高很多倍,随机 IOPS 更是快了上千倍。

三、CPU 和内存硬件

几个基本的指标:

  • CPU 的时钟频率,也就是主频。主频反映了 CPU 工作节拍,也就直接决定了 CPU 周期大小。
  • CPI 和 IPC:CPI衡量平均每条指令的平均时钟周期个数。它的反面是 IPC。虽然一个指令的执行过程需要多个周期,但 IPC 是可以大于 1 的,因为现代 CPU 都采用流水线结构。一般来讲,测量应用程序运行时的 IPC,如果低于 1,这个运行的系统性能就不是太好,需要做些优化来提高 IPC。
  • MIPS:每秒执行的百万指令数。我们经常会需要比较不同 CPU 硬件的性能,MIPS 就是一个很好的指标,一般来讲,MIPS 越高,CPU 性能越高。MIPS 可以通过主频和 IPC 相乘得到,也就是说 MIPS= 主频×IPC
  • CPU 缓存:一般 CPU 都有几级缓存,分别称为 L1、L2、L3。L3 是最后一级缓存。

image.png

值得一提的是现在的 NUMA 处理器会有本地和远端内存的区别,当访问本地节点的内存是会快一些。

四、操作系统和应用程序相关

我们刚刚谈了硬件方面,下面看看软件,也就是操作系统和应用程序。

1、几个重要概念和指标

  • 指令分支延迟:CPU 需要先获取指令,然后才能执行。获取下一条指令时需要知道指令地址,如果这个地址需要根据现有的指令计算结果才能决定,那么就构成了指令分支。CPU 通常会采取提前提取指令这项优化来提高性能,但是如果是指令分支,那么就可能预测错误,预先提取的指令分支并没有被执行。
  • 互斥加锁和解锁:互斥锁(也叫 Lock)是在多线程中用来同步的,可以保证没有两个线程同时运行在受保护的关键区域。
  • 上下文切换:多个进程或线程共享 CPU 的时候,就需要经常做上下文切换。这种切换在 CPU 时间和缓存上都很大代价;尤其是进程切换。

image.png

2、Linux 平均负载

系统过载并超过1.0的负载值有时不是问题,因为即使有一些延迟,CPU也会处理队列中的作业,负载将再次降低到1.0以下的值。但是如果系统的持续负载值大于1,则意味着它无法吸收执行中的所有负载,因此其响应时间将增加,系统将变得缓慢且无响应。高于1的高值,尤其是最后5分钟和15分钟的负载平均值是一个明显的症状,要么我们需要改进计算机的硬件,通过限制用户可以对系统的使用来节省更少的资源,或者除以多个相似节点之间的负载。

因此,我们提出以下建议:

  • >=0.70:没有任何反应,但有必要监控 CPU 负载。如果在一段时间内保持这种状态,就必须在事情变得更糟之前进行调查
  • >=1.00存在问题,您必须找到并修复它,否则系统负载的主要高峰将导致您的应用程序变慢或无响应。
  • >=3.00:你的系统变得 非常慢。甚至很难从命令行操作它来试图找出问题的原因,因此修复问题需要的时间比我们之前采取的行动要长。你冒的风险是系统会更饱和并且肯定会崩溃。
  • >=5.00你可能无法恢复系统。你可以等待奇迹自发降低负载,或者如果你知道发生了什么并且可以负担得起,你可以在控制台中启动 kill -9 <process_name> 之类的命令 ,并祈求它运行在某些时候,以减轻系统负荷并重新获得其控制权。否则,你肯定别无选择,只能重新启动计算机。

五、网络相关

网络的传输延迟是和地理距离相关的。网络信号传递速度不可能超过光速,一般光纤中速度是每毫秒 200 公里左右。如果考虑往返时间(RTT),那么可以大致说每 100 公里就需要一毫秒。

在机房里面,一般的传输 RTT 不超过半毫秒。如果是同一个机柜里面的两台主机之间,那么延迟就更小了,小于 0.1 毫秒。

另外要注意的是,传输延迟也取决于传输数据的大小,因为各种网络协议都是按照数据包来传输的,包的大小会有影响。比如一个 20KB 大小的数据,用 1Gbps 的网络传输,仅仅网卡发送延迟就是 0.2 毫秒。

image.png

六、中间件相关

先说说负载均衡,硬负载性能远远高于软负载。Ngxin 的性能是万级;LVS 的性能是十万级,据说可达到 80 万 / 秒;而 F5 性能是百万级,从 200 万 / 秒到 800 万 / 秒都有(数据来源网络,仅供参考,如需采用请根据实际业务场景进行性能测试)。当然,软件负载均衡的最大优势是便宜,一台普通的 Linux 服务器批发价大概就是 1 万元左右,相比 F5 的价格,那就是自行车和宝马的区别了。
image.png

具体的数值和机器配置以及测试案例有关,但大概的量级不会变化很大。

如果是业务系统,由于业务复杂度差异很大,有的每秒 500 请求可能就是高性能了,因此需要针对业务进行性能测试,确立性能基线,方便后续测试做比较。

七、网站规模

这里就大致根据理论最大TPS,给网站做几个分类:

image.png

  • 小网站:没什么好说的,简单的小网站而已,你可以用最简单的方法快速搭建,短期没有太多的技术瓶颈,只要服务器不要太烂就好。

  • DB极限型:大部分的关系型数据库的每次请求大多都能控制在 10ms 左右,即便你的网站每页面只有一次DB请求,那么页面请求无法保证在1秒钟内完成100个请求,这个阶段要考虑做 Cache 或者多 DB负 载。无论那种方案,网站重构是不可避免的。

  • 带宽极限型:目前服务器大多用了 IDC 提供的“百兆带宽”,这意味着网站出口的实际带宽是 8M Byte 左右。假定每个页面只有 10K Byte,在这个并发条件下,百兆带宽已经吃完。首要考虑是 CDN加速/异地缓存,多机负载等技术。

  • 内网带宽极限+cache极限型:由于 Key/value 的特性,每个页面对 cache 的请求远大于直接对DB的请求,cache 的悲观并发数在 2w 左右,看似很高,但事实上大多数情况下,首先是有可能在次之前内网的带宽就已经吃光,接着是在 8K QPS左右的情况下,cache已经表现出了不稳定,如果代码上没有足够的优化,可能直接将压力穿透到了DB层上,这就最终导致整个系统在达到某个阀值之上,性能迅速下滑。

  • FORK/SELECT,锁模式极限型:一句话:线程模型决定吞吐量。不管你系统中最常见的锁是什么锁,这个级别下,文件系统访问锁都成为了灾难。这就要求系统中不能存在中央节点,所有的数据都必须分布存储,数据需要分布处理。总之,关键词:分布

  • C10K极限:尽管现在很多应用已经实现了 C25K,但短板理论告诉我们,决定网站整体并发的永远是最低效的那个环节。

八、服务器规模

我们可以来算一下,根据行业内的经验,可以估计如下的投入:

image.png
可以看到,十万用户到上亿用户,也就多了 100 倍,为什么服务器需要 1000 倍?这完全不是呈线性的关系。

这时因为,当架构变复杂了后,你就要做很多非功能的东西了,比如,缓存、队列、服务发现、网关、自动化运维、监控等。

九、总结

今天分享了几组性能数字,希望起到抛砖引玉的效果。你可以在此基础上,在广度和深度上继续扩展。

参考资料:

  • [1]:《左耳听风》
  • [2]:《从0开始学架构》
  • [3]:《性能工程高手课》
目录
相关文章
|
6月前
|
存储 缓存 负载均衡
常用性能数字
【2月更文挑战第26天】常用性能数字
75 3
常用性能数字
|
6月前
1657.确定两个字符串是否接近
1657.确定两个字符串是否接近
48 0
|
编解码 芯片 内存技术
数字基带传输系统 1
数字基带传输系统
266 0
|
机器人 Java 开发工具
生成指定长度的随机数字,用对方法精准提效数10倍!
生成指定长度的随机数字这一函数功能可能在以下情况下被使用:
数字基带传输系统 2
数字基带传输系统
201 0
|
编解码
数字基带传输系统 3
数字基带传输系统
113 0
|
传感器 芯片
模拟量与数字量区别
模拟量与数字量区别
191 0
|
存储 测试技术
0~n-1中缺失的数字(简单难度)
0~n-1中缺失的数字(简单难度)
118 0
0~n-1中缺失的数字(简单难度)
|
存储 测试技术
只出现一次的数字(简单难度)
只出现一次的数字(简单难度)
99 0
只出现一次的数字(简单难度)
|
Rust 自然语言处理 算法
【算法】1365. 有多少小于当前数字的数字(多语言实现)
给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。 换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。 以数组形式返回答案。
【算法】1365. 有多少小于当前数字的数字(多语言实现)