深刻淺出計算機組成原理學習筆記:第四十四講

在專欄一開始的時候,我和你說過,在計算機組成原理這門課裏面,不少設計的核心思路,都來源於性能。在前免講解CPU的時候,相信你已經有了切身的感覺了。ios

大部分程序員開發的都是應⽤系統。在開發應用系統的時候,咱們遇到的性能瓶頸大部分都在I/O上。在第36講講解局部性原理的時候,咱們一塊兒看了經過把內存看成是緩存,
來提高系統的總體性能。在第37講講解CPU Cache的時候,咱們一塊兒看了CPU Cache和主內存之間性能的巨大差別nginx


然而,咱們知道,並非全部問題都能靠利⽤內存或者CPU Cache作一層緩存來解決。特別是在這個「大數據」的時代。咱們在硬盤上存儲了愈來愈多的數據,
一個MySQL數據庫的單表有個幾千萬條記錄,早已經不算是什麼罕見現象了。這也就意味着,用內存當緩存,存儲空間是不夠用的。大部分時間,
咱們的請求仍是要打到硬盤上。那麼,這⼀講咱們就來看看硬盤I/O性能的事兒。程序員

1、隨機IO

一、硬盤廠商

二、數據傳輸率

HDD硬盤

SSD硬盤

三、響應時間

Acc.Time

指標和平常的經驗不符啊

光看響應時間和吞吐率這兩個指標,彷佛咱們的硬盤性能很不錯、咱們平時往數據庫裏寫入一條記錄,也就是1KB左右的大小。咱們拿200MB去除以1KB,數據庫

也可以在幾毫秒時間返回、一秒鐘可以傳輸的數據,也有200MB左右緩存

順序讀寫和隨機讀寫

隨機讀寫bash

順序讀寫服務器

2、OPS和DTR纔是輸入輸出性能的核心指標

實際開發中對數據的訪問

服務器承受的「併發」

3、性能瓶頸在

硬盤性能

CPU性能

和咱們硬盤可以進⾏的操做數,也有好一個數量級的差別,由於不少時候,CPU指令發出去以後,不得不去「等」咱們的I/O操做完成,才能進入下一步的操做併發

4、如何定位IO_WAIT?

那麼,在實際遇到服務端程序的性能問題的時候,咱們怎麼知道這個問題是否是來自於CPU等I/O來完成操做呢?彆着急,咱們接下來,
就經過top和iostat這些命令,一塊兒來看看CPU到底有沒有在等待io操做。性能

一、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

二、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」這個命令。測試

三、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是怎麼樣的。

四、完整案例

我在一臺雲平臺上的單個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來模擬其餘更多不一樣的性能壓力,看看咱們的機器負載會發生什麼變化。

5、總結延伸 

這一講裏,咱們從硬盤的兩個核心指標,響應時間和數據傳輸率,來理解和研究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的瓶頸,以及這些瓶頸來自於哪些程序,你就能夠根據定位的結果來優化你本身的程序了。

相關文章
相關標籤/搜索