性能基础之硬盘性能知识必知必会

2024-08-21 10:44

本文主要是介绍性能基础之硬盘性能知识必知必会,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、常见硬盘分类
  • 二、基础原理知识
  • 三、常见性能指标
  • 四、IO 性能分析思路

一、常见硬盘分类

硬盘有很多种,常用的是机械硬盘(HDD)和固态硬盘(SSD)。这里简单回顾下,机械硬盘是传统普通硬盘,它的构成主要由盘片,磁头、盘片转轴、控制电机、磁头控制器等部件构成,读写速度和转速(通常上万转)相关;而SSD盘是以固态电子存储芯片阵列组成,包括如闪存芯片、控制芯片、缓存芯片等。其实还有混合硬盘,在机械硬盘上加以闪存颗粒作为缓存以提升性能。

典型的HDD和SSD示意图:
在这里插入图片描述
(图片来自网络)

由于其结构的不同,二者在性能等多方面也差异巨大。一般来说,SSD比HDD机械硬盘在访问性能上是数十倍,能耗(质量、体积、功耗)和可靠性(防震、耐温)各方面上也有很大提升,所以现在的PC/笔记本等大多已选择了SSD固态硬盘。而HDD硬盘一般在容量、成本和寿命上更有优势。

SSD 的种类很多,按照技术来说有单层(SLC)和多层(MLC,TLC 等)。按照质量和性能来分,有企业级和普通级。根据安装的接口和协议来分,有 SAS、SATA、PCIe 和 NVMe 等。

二、基础原理知识

硬盘 I/O 其实是挺复杂的一个逻辑,但我们今天只说在做性能分析的时候,应该如何定位问题。在这之前需要先理解一下文件的一个重要的属性:inode。

什么是 inode 呢?先来看一个示意图:
在这里插入图片描述

磁盘上最小的存储单元是扇区 sector,每8个扇区组成一个块 I/O Block Size(4096字节)。如下所示:

[root@7DGroup2 ~]# tune2fs -l /dev/vda1|grep  Block
Block count:              10485504
Block size:               4096
Blocks per group:         32768
[root@7DGroup2 ~]#

文件的存储就是由这些块组成的,当块多了之后就成了如下这样(其实磁盘上的块比这个图中多得多,这里只是示意图):

在这里插入图片描述

其中红色的这部分是存储的文件,我们通常在文件系统中直接ls或者用其他命令操作文件的时候是根据路径来操作的,那些是上层的命令。当我们执行了一个命令之后,操作系统会来找到这些文件做相应的操作,怎么找到这些文件呢,那就需要 inode 了。

Inode 用来存储这些文件的元信息,也就是索引节点,它包括的信息有:

  • 字节数
  • User ID
  • Group ID
  • 读、写、执行权限
  • 时间戳,共有三个:ctime 指 inode 上一次变动的时间,mtime 指文件内容上一次变动的时间,atime 指文件上一次打开的时间
  • 链接数,有多少文件名指向这个 inode
  • 文件数据 block 的位置

通过这些信息,我们才能实现对文件的操作。这个 inode 其实也是存储在磁盘上的,也需要占用一些空间,如上图中的绿色部分所示。

当我们在系统级看到 IO 过高的时候,比如下图所示:
在这里插入图片描述
从上图可以看到,这系统几乎所有的 CPU 都在等 IO。这时怎么办?就用我们后面提到的分析的思路,查看进程级和线程级的 IO,进而找到具体的文件。

三、常见性能指标

对于I/O密集型系统,其性能指标最重要的是以下三个:

  • 吞吐量(Throughput):每秒的读写数据量,衡量的是存储系统的实际数据传输速率,通常以 MB/s 或 GB/s 为单位。类似如:吞吐率、带宽、传输率等。
  • 时延(Latency):I/O 操作的发送到接收确认所经过的时间,常以为毫秒单位,对这一性能指标,我们通常会考虑它的平均值和高位百分数,比如 P99、P95。类似如:响应时间、请求时间等。
  • IOPS(I/O per second):每秒读/写次数,单位为次(计数),这是衡量存储性能的主要指标之一。每个 IO 的请求都有自己的特性,比如读还是写,是顺序读写还是随机读写,IO 的大小是多少等。类似如:系统并发量、每秒请求QPS等。

一般来讲,IOPS 与吞吐量是紧密相关的。长时间的同类任务,通常系统吞吐量高更重要;短时间的随机任务,系统的时延小更重要,而在时延保证的前提下,IOPS 越高系统的服务能力越强。

另外,读写块大小(I/O Block Size)是非常重要的因素。在具体的性能分析中,吞吐量和IOPS有如下关系:

T h r o u g h p u t = I O P S ∗ B l o c k S i z e Throughput = IOPS * Block Size Throughput=IOPSBlockSize

注:吞吐量等于 IOPS 和 IO 读写块大小的乘积。

这个也很容易理解,比如对一个硬盘的读写 IO 是 1MB,硬盘的 IOPS 是 100,那么硬盘总的吞吐量就是 100 MB/s,需要强调的是,这里 IO 的具体特性很重要,比如是顺序还是随机,IO 大小等。

所以在分析最大吞吐量和最大IOPS时,需要针对地选择BlockSize;提升BlockSize,通常会使系统吞吐量提升,系统IOPS下降。

另外,最大峰值性能(maximum performance)不同于可持续性能(sustained performance),所以在性能分析时需要维持一段时间的稳定负载并统计平均值。

还有一点要注意,有些系统会因为其 IO 队列深度增加,而获得更好的 IO 性能;比如吞吐量会升高,平均访问时延会降低。这是因为存储系统的 IO 队列处理机制,可以对 IO 进行重新排序,从而获得好的性能。比如,它可以合并几个相邻的 IO,把随机 IO 重新排序为顺序 IO 等。

以下为不同硬盘类别性能指标参考数据:
在这里插入图片描述

四、IO 性能分析思路

构建 I/O 分析决策树:
在这里插入图片描述

先聊下磁盘系统结构:

  • 如果是IDE驱动器,磁盘命名为:hda、hdb、hdc等;
  • 如果是SCSI驱动器,磁盘命名为:sda、sdb、sdc等
  • 磁盘通常被分成多个分区,分区设备的名称是通过将分区号添加到基本设备名称的末尾来创建的,每个单独的分区通常包含一个文件系统或一个交换分区,按照 /etc/fstab 中的指定,这些分区被装载到 Linux 根文件系统中。这些挂载的文件系统包含应用程序读写的文件。
  • 当应用程序执行读或写操作时,Linux 内核可能会将文件的副本存储在其缓存或缓冲区中,并在不访问磁盘的情况下返回所请求的信息。但是,如果 Linux 内核没有存储在内存中的数据副本,它会向磁盘的 I/O 队列添加一个请求。如果 Linux 内核注意到多个请求请求磁盘上的连续位置,它会将它们合并为一个大请求。这种合并消除了第二个请求的寻道时间,从而提高了总体磁盘性能。当请求被放入磁盘队列时,如果磁盘当前不忙,它将开始为 I/O 请求提供服务。如果磁盘正忙,请求将在队列中等待,直到驱动器可用,然后对其进行服务。

在这一层咱们主要关注 I/O ,既然是关注 I/O ,如果 I/O 高应该怎么去分析?怎么定位?

vmstat [-D] [-d] [-p 分区] 

参数说明:

  • d:显示磁盘相关统计信息。
  • D: 显示 Linux I/O 子系统的总统计信息,统计数据是自系统启动以来的总数
  • p: 统计数据是自系统启动以来的总数,而不仅仅是此示例和上一个示例之间发生的总数。

在这里插入图片描述

[root@ ~]# vmstat 1 10
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st1  0      0 261712 144188 2935000    0    0     2    12   74   84  1  1 99  0  00  0      0 261728 144188 2935032    0    0     0    84 1244 2384  1  1 98  0  00  0      0 261484 144188 2935032    0    0     0     8 1508 2439  1  1 98  0  00  0      0 261612 144188 2935032    0    0     0     0 1270 2558  2  1 98  0  00  0      0 261604 144188 2935032    0    0     0     0 1111 2134  1  1 98  0  00  0      0 261604 144188 2935032    0    0     0     0 1222 2401  1  1 99  0  00  0      0 261480 144188 2935032    0    0     0     0 1515 2951  2  1 97  0  00  0      0 260688 144188 2935032    0    0     0    12 1466 2569  2  2 97  0  00  0      0 261064 144188 2935032    0    0     0     0 1828 3418  3  2 95  0  00  0      0 261232 144188 2935032    0    0     0     0 1089 2100  1  0 99  0  0

使用 vmstat 中关于磁盘也就是 bo/bi/wa:

  • bo 这表示在前一间隔内写入磁盘的块总数。(在vmstat中,磁盘的块大小通常为1024字节)
  • bi 显示在上一间隔中从磁盘读取的块数。(在vmstat中,磁盘的块大小通常为1024字节)
  • wa 表示等待I/O完成所花费的CPU时间,每秒写入磁盘块的速率。

在 Linux 操作系统中 I/O 分析最常见的命令是 iostat, 这个工具可以查看进程发出 IO 请求的数量、系统处理 IO 请求的耗时、磁盘的利用率等,也可以分析进程与操作系统的交互过程中 IO 方面是否存在瓶颈。

# iostat [参数] [时间] [次数]
iostat -d -x -k 1 10

参数说明:

  • -c:显示 CPU 使用情况
  • -d:显示磁盘使用情况
  • -k:以 K 为单位显示
  • -m:以 M 为单位显示
  • -N:显示磁盘阵列(LVM) 信息
  • -n:显示 NFS 使用情况
  • -p:可以报告出每块磁盘的每个分区的使用情况
  • -t:显示终端和 CPU 的信息
  • -x:显示详细信息

在这里插入图片描述

计数器信息的含义:

  • rrqm/s:每秒这个设备相关的读取请求有多少被 Merge了(当系统调用需要读取数据的时候,VFS 将请求发到各个 FS,如果 FS 发现不同的读取请求读取的是相同 Block 的数据,FS会将这个请求合并Merge)
  • wrqm/s:每秒这个设备相关的写入请求有多少被 Merge 了
  • r/s:每秒读取数
  • w/s:每秒写入数
  • rKB/s:每秒向设备发出的读请求数
  • wKB/s:每秒向设备发出的写请求数
  • avgrq-sz:平均请求扇区的大小
  • avgqu-sz:是平均请求队列的长度。毫无疑问,队列长度越短越好。
  • await:每一个 I/O 请求的处理的平均时间(单位是微秒毫秒)。这里可以理解为 I/O 的响应时间,一般系统 I/O 响应时间应该低于 5ms,如果大于 10ms就比较大了。这个时间包括了队列时间和服务时间,也就是说,一般情况下,await 大于 svctm,它们的差值越小,则说明队列时间越短,反之差值越大,队列时间越长,说明系统出了问题。
  • w_await:表示写入的平均响应时间
  • r_await:表示读取的平均响应时间
  • svctm:表示平均每次设备 I/O 操作的服务时间(以毫秒为单位)。如果 svctm 的值与 await 很接近,表示几乎没有 I/O 等待,磁盘性能很好,如果 await 的值远高于 svctm 的值,则表示 I/O 队列等待太长,系统上运行的应用程序将变慢。这个数可以参考,但不一定准
  • %util:在统计时间内所有处理 I/O 时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有 0.8 秒在处理 I/O,而 0.2 秒闲置,那么该设备的 %util = 0.8/1 = 80%,所以该参数暗示了设备的繁忙程度。一般地,如果该参数是 100 %表示设备已经接近满负荷运行了(当然如果是多磁盘,即使 %util 是 100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)

常见用法:

iostat -d -k 1 10    #查看 TPS 和吞吐量信息(磁盘读写速度单位为 KB)
iostat -d -m 2       #查看 TPS 和吞吐量信息(磁盘读写速度单位为 MB)
iostat -d -x -k 1 10 #查看设备使用率(%util)、响应时间(await) 
iostat -c 1 10       #查看 cpu 状态
iostat -c 1 10       #查看 cpu 状态

注意点:

  • 网卡的大吞吐量可能导致更多的 cup
  • 大量的 cup 开销又会增加更多内存使用请求
  • 大量内存与磁盘的请求可能导致更多的 cpu 以及 IO 问题

主要关注计数器:

  • util
  • avgqu-sz
  • await
  • svtm
  • r/s
  • w/s

出现瓶颈的计数器:

  • %util 很高(接近100%)
  • await 远大于 svctm(差值越大,队列时间越长)
  • avgqu-sz 比较大(队列长度越短越好)
  • cpu > wa 过大 (参考值超过 20)
  • system > bi&bo 过大(参考值超过 2000)

而 IO/s(IOPS) 的关键计算示例是这样的:

IO/s = r/s + w/s = 18.33+114.33 = 132.66
%util = ( (IO/s * svctm) /1000) * 100% = 100.02564%

这个%util是用svctm算来的,既然svctm都不一定准了,那这个值也只能参考了。还好我们还有其他工具可以接着往深了去定位,所以,接下来,我们得查一下是什么程序写的。这里我们用 iotop 命令查看:

Total DISK READ :       2.27 M/s | Total DISK WRITE :    574.86 M/s
Actual DISK READ:       3.86 M/s | Actual DISK WRITE:      34.13 M/sTID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND394 be/3 root        0.00 B/s  441.15 M/s  0.00 % 85.47 % [jbd2/vda1-8]
32616 be/4 root     1984.69 K/s    3.40 K/s  0.00 % 42.89 % kube-controllers
13787 be/4 root        0.00 B/s    0.00 B/s  0.00 % 35.41 % [kworker/u4:1]
...............................

从上面的Total DISK WRITE/READ就可以知道当前的读写到底有多少了,默认是按照I/O列来排序的,这里有Total,也有Actual,并且这两个并不相等,为什么呢?

因为 Total 的值显示的是用户态进程与内核态进程之间的速度,而 Actual 显示的是内核块设备子系统与硬件之间的速度。

在这里插入图片描述
(图片来自《性能测试实战 30 讲》)

而在I/O交互中,由于存在cache和在内核中会做I/O排序,因此这两个值并不会相同。那如果你要说磁盘的读写能力怎么样,我们应该看的是Actual。这个没啥好说的,因为Total再大,不能真实写到硬盘上也是没用的。

在以上的线程列表中,通过排序,就可以知道是哪个线程(注意在第一列是 TID 哦)占的I/O高了。

参考资料:

  • 高楼《性能测试实战 30 讲》
  • 高楼《性能分析之从 IO 高定位到具体文件》
  • 《linux 磁盘IO测试工具:fio (同时简要介绍dd工具测试)》

这篇关于性能基础之硬盘性能知识必知必会的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1092940

相关文章

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Tomcat高效部署与性能优化方式

《Tomcat高效部署与性能优化方式》本文介绍了如何高效部署Tomcat并进行性能优化,以确保Web应用的稳定运行和高效响应,高效部署包括环境准备、安装Tomcat、配置Tomcat、部署应用和启动T... 目录Tomcat高效部署与性能优化一、引言二、Tomcat高效部署三、Tomcat性能优化总结Tom

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

MySQL中my.ini文件的基础配置和优化配置方式

《MySQL中my.ini文件的基础配置和优化配置方式》文章讨论了数据库异步同步的优化思路,包括三个主要方面:幂等性、时序和延迟,作者还分享了MySQL配置文件的优化经验,并鼓励读者提供支持... 目录mysql my.ini文件的配置和优化配置优化思路MySQL配置文件优化总结MySQL my.ini文件

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物