• 深入浅出计算机组成原理学习笔记:第四十四讲


    在专栏一开始的时候,我和你说过,在计算机组成原理这门课里面,很多设计的核心思路,都来源于性能。在前免讲解CPU的时候,相信你已经有了切身的感受了。

    大部分程序员开发的都是应⽤系统。在开发应用系统的时候,我们遇到的性能瓶颈大部分都在I/O上。在第36讲讲解局部性原理的时候,我们一起看了通过把内存当作是缓存,
    来提升系统的整体性能。在第37讲讲解CPU Cache的时候,我们一起看了CPU Cache和主内存之间性能的巨大差异


    然而,我们知道,并不是所有问题都能靠利⽤内存或者CPU Cache做一层缓存来解决。特别是在这个“大数据”的时代。我们在硬盘上存储了越来越多的数据,
    一个MySQL数据库的单表有个几千万条记录,早已经不算是什么罕见现象了。这也就意味着,用内存当缓存,存储空间是不够用的。大部分时间,
    我们的请求还是要打到硬盘上。那么,这⼀讲我们就来看看硬盘I/O性能的事儿。

    一、随机IO

    1、硬盘厂商

    2、数据传输率

    HDD硬盘

    SSD硬盘

    3、响应时间

    Acc.Time

    指标和日常的经验不符啊

    光看响应时间和吞吐率这两个指标,似乎我们的硬盘性能很不错、我们平时往数据库里写入一条记录,也就是1KB左右的大小。我们拿200MB去除以1KB,

    也能够在几毫秒时间返回、一秒钟能够传输的数据,也有200MB左右

    顺序读写和随机读写

    随机读写

    顺序读写

    二、OPS和DTR才是输入输出性能的核心指标

    实际开发中对数据的访问

    服务器承受的“并发”

    三、性能瓶颈在

    硬盘性能

    CPU性能

    和我们硬盘能够进⾏的操作数,也有好一个数量级的差异,因为很多时候,CPU指令发出去之后,不得不去“等”我们的I/O操作完成,才能进入下一步的操作

    四、如何定位IO_WAIT?

    那么,在实际遇到服务端程序的性能问题的时候,我们怎么知道这个问题是不是来自于CPU等I/O来完成操作呢?别着急,我们接下来,
    就通过top和iostat这些命令,一起来看看CPU到底有没有在等待io操作。

    1、top

    top - 06:26:30 up 4 days, 53 min,  1 user,  load average: 0.79, 0.69, 0.65
    Tasks: 204 total,   1 running, 203 sleeping,   0 stopped,   0 zombie
    %Cpu(s): 20.0 us,  1.7 sy,  0.0 ni, 77.7 id,  0.0 wa,  0.0 hi,  0.7 si,  0.0 st
    KiB Mem:   7679792 total,  6646248 used,  1033544 free,   251688 buffers
    KiB Swap:        0 total,        0 used,        0 free.  4115536 cached Mem

    2、iowat

    avg-cpu:  %user   %nice %system %iowait  %steal   %idle
              17.02    0.01    2.18    0.04    0.00   80.76
    Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
    sda               1.81         2.02        30.87     706768   10777408
    

    你会看到,这个命令⾥,不仅有iowait这个CPU等待时间的百分⽐,还有⼀些更加具体的指标了,并且它还是按照你机器上安装的多块不同的硬盘划分的。

    这⾥的tps指标,其实就对应着我们上⾯所说的硬盘的IOPS性能。⽽kB_read/s和kB_wrtn/s指标,就对应着我们的数据传输率的指标。

    知道实际硬盘读写的tps、kB_read/s和kb_wrtn/s的指标,我们基本上可以判断出,机器的性能是不是卡在I/O上了。那么,接下来,
    我们就是要找出到底是哪一个进程是这些I/O读写的来源了。这个时候,你需要“iotop”这个命令。

    3、iotop

    iotop
    Total DISK READ :       0.00 B/s | Total DISK WRITE :      15.75 K/s
    Actual DISK READ:       0.00 B/s | Actual DISK WRITE:      35.44 K/s
      TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                             
      104 be/3 root        0.00 B/s    7.88 K/s  0.00 %  0.18 % [jbd2/sda1-8]
      383 be/4 root        0.00 B/s    3.94 K/s  0.00 %  0.00 % rsyslogd -n [rs:main Q:Reg]
     1514 be/4 www-data    0.00 B/s    3.94 K/s  0.00 %  0.00 % nginx: worker process
    

    通过iotop这个命令,你可以看到具体是哪⼀个进程实际占⽤了⼤量I/O,那么你就可以有的放⽮,去优化对应的程序了。

    上面的这些示例里,不管是wa也好,tps也好,它们都很小。那么,接下来,我就给你用Linux下,用stress命令,来模拟一个高I/O复杂的情况,来看看这个时候的iowait是怎么样的。

    4、完整案例

    我在一台云平台上的单个CPU核⼼的机器上输⼊“stress-i2”,让stress这个程序模拟两个进程不停地从内存里往硬盘上写数据。

    stress -i 2
    

    top查看负载和wa

    top
    top - 06:56:02 up 3 days, 19:34,  2 users,  load average: 5.99, 1.82, 0.63
    Tasks:  88 total,   3 running,  85 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  3.0 us, 29.9 sy,  0.0 ni,  0.0 id, 67.2 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem :  1741304 total,  1004404 free,   307152 used,   429748 buff/cache
    KiB Swap:        0 total,        0 free,        0 used.  1245700 avail Mem 
    

    iowat查看iops

    iostat 2 5
    avg-cpu:  %user   %nice %system %iowait  %steal   %idle
               5.03    0.00   67.92   27.04    0.00    0.00
    Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
    sda           39762.26         0.00         0.00          0          0
    

    如果我们通过iostat,查看硬盘的I/O,你会看到,里面的tps很快就到了4万左右,占满了对应硬盘的IOPS。

    iotop查看io占用排行榜

    iotop
    Total DISK READ :       0.00 B/s | Total DISK WRITE :       0.00 B/s
    Actual DISK READ:       0.00 B/s | Actual DISK WRITE:       0.00 B/s
      TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                             
    29161 be/4 xuwenhao    0.00 B/s    0.00 B/s  0.00 % 56.71 % stress -i 2
    29162 be/4 xuwenhao    0.00 B/s    0.00 B/s  0.00 % 46.89 % stress -i 2
        1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % init
    

    相信到了这里,你也应该学会了怎么通过top、iostat以及iotop,一步一步快速定位服务器端的I/O带来的性能瓶颈了。
    你也可以自己通过Linux的man命令,看一看这些命令还有哪些参数,以及通过stress来模拟其他更多不同的性能压力,看看我们的机器负载会发生什么变化。

    五、总结延伸 

    这一讲里,我们从硬盘的两个核心指标,响应时间和数据传输率,来理解和研究I/O的性能问题。你也自己可以通过as ssd这样的性能评测软件,看一看自己的硬盘性能。

    在顺序读取的情况下,无论是HDD硬盘还是SSD硬盘,性能看起来都是很不错的。不过,等到进行随机读取测试的时候,硬盘的性能才能见了真章。因为在大部分的应用开发场景下,
    我们关注的并不是在顺序读写下的数据量,而是每秒钟能够进行输入输出的操作次数,也就是IOPS这个核心性能指标。

    你会发现,即使是使PCI Express接口的SSD硬盘,IOPS也就只是到了2万左右。这个性能,和我们CPU的每秒20亿次操作的能⼒⽐起来,可就差得远了。
    所以很多时候,我们的程序对外响应慢,其实都是CPU在等待I/O操作完成。


    在Linux下,我们可以通过top这样的命令,来看整个服务器的整体负载。在应⽤响应慢的时候,我们可以先通过这个指令,来看CPU是否在等待I/O完成⾃⼰的操作。
    进一步地,我们可以通过iostat这个命令,来看到各个硬盘这个时候的读写情况。⽽iotop这个命令,能够帮助我们定位到到底是哪⼀个进程在进行大量的I/O操作。

    这些命令的组合,可以快速帮你定位到是不是我们的程序遇到了I/O的瓶颈,以及这些瓶颈来自于哪些程序,你就可以根据定位的结果来优化你自己的程序了。

  • 相关阅读:
    IDEA04 工具窗口管理、各种跳转、高效定位、行操作、列操作、live template、postfix、alt enter、重构、git使用
    Maven01 环境准备、maven项目结构、编译/测试/打包/清除、安装、
    SpringBoot31 整合SpringJDBC、整合MyBatis、利用AOP实现多数据源
    Docker03 Docker基础知识、Docker实战
    [leetcode数组系列]2三数之和
    [leetcode数组系列]1 两数之和
    时间复杂度总结
    《将博客搬至CSDN》
    5 系统的软中断CPU升高,一般处理办法?
    python数据分析5 数据转换
  • 原文地址:https://www.cnblogs.com/luoahong/p/11363137.html
Copyright © 2020-2023  润新知