Linux性能優化實戰學習筆記:第三十一講

1、上節回顧

上一節,咱們一塊兒回顧了常見的文件系統和磁盤 I/O 性能指標,梳理了核心的 I/O 性能觀測工具,最後還總結了快速分析 I/O 性能問題的思路。ios

雖然 I/O 的性能指標不少,相應的性能分析工具也有好幾個,但理解了各類指標的含義後,你就會發現它們其實都有必定的關聯。算法

順着這些關係往下理解,你就會發現,掌握這些經常使用的瓶頸分析思路,其實並不難。找出了 I/O 的性能瓶頸後,下一步要作的就是優化了,也就是如何以最快的速度完成 I/Oubuntu

操做,或者換個思路,減小甚至避免磁盤的 I/O 操做。今天,我就來講說,優化 I/O 性能問題的思路和注意事項。緩存

2、I/O 基準測試

按照個人習慣,優化以前,我會先問本身, I/O 性能優化的目標是什麼?換句話說,咱們觀察的這些 I/O 性能指標(好比 IOPS、吞吐量、延遲等),要達到多少才合適呢?性能優化

事實上,I/O 性能指標的具體標準,每一個人估計會有不一樣的答案,由於咱們每一個人的應用場景、使用的文件系統和物理磁盤等,都有可能不同。bash

爲了更客觀合理地評估優化效果,咱們首先應該對磁盤和文件系統進行基準測試,獲得文件系統或者磁盤 I/O 的極限性能。網絡

fio(Flexible I/O Tester)正是最經常使用的文件系統和磁盤 I/O 性能基準測試工具。它提供了大量的可定製化選項,能夠用來測試,裸盤或者文件系統在各類場景下的 I/O 性能,包
括了不一樣塊大小、不一樣 I/O 引擎以及是否使用緩存等場景。fio 的安裝比較簡單,你能夠執行下面的命令來安裝它:異步

# Ubuntu
apt-get install -y fio

root@luoahong:~# apt-get --fix-broken install
E: dpkg was interrupted, you must manually run 'dpkg --configure -a' to correct the problem.
root@luoahong:~# dpkg --purge fio
dpkg: warning: ignoring request to remove fio which isn't installed
root@luoahong:~# apt-get install -y fio
Reading package lists... Done
Building dependency tree
......
Setting up fio (3.1-1) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
W: APT had planned for dpkg to do more than it reported back (45 vs 49).
   Affected packages: man-db:amd64

一、fio基準測試

安裝完成後,就能夠執行 man fio 查詢它的使用方法。
fio 的選項很是多, 我會經過幾個常見場景的測試方法,介紹一些最經常使用的選項。這些常見場景包括隨機讀、隨機寫、順序讀以及順序寫等,你能夠執行下面這些命令來測試:ionic

隨機讀

[root@luoahong ~]# fio -name=randread -direct=1 -iodepth=64 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sda
randread: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=64
fio-3.1
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=5088KiB/s,w=0KiB/s][r=1272,w=0 IOPS][eta 00m:00s]
randread: (groupid=0, jobs=1): err= 0: pid=10300: Wed Sep  4 10:38:44 2019
   read: IOPS=267, BW=1071KiB/s (1096kB/s)(1024MiB/979315msec)
    slat (nsec): min=1031, max=203759k, avg=50478.54, stdev=1172919.69
    clat (usec): min=269, max=3218.8k, avg=239027.70, stdev=215031.80
     lat (usec): min=485, max=3218.8k, avg=239079.19, stdev=215027.75
    clat percentiles (msec):
     |  1.00th=[   20],  5.00th=[   43], 10.00th=[   61], 20.00th=[   93],
     | 30.00th=[  123], 40.00th=[  153], 50.00th=[  184], 60.00th=[  222],
     | 70.00th=[  271], 80.00th=[  347], 90.00th=[  477], 95.00th=[  600],
     | 99.00th=[  978], 99.50th=[ 1418], 99.90th=[ 2198], 99.95th=[ 2366],
     | 99.99th=[ 2567]
   bw (  KiB/s): min=  280, max= 4311, per=99.75%, avg=1067.32, stdev=326.74, samples=1958
   iops        : min=   70, max= 1077, avg=266.61, stdev=81.72, samples=1958
  lat (usec)   : 500=0.01%, 1000=0.01%
  lat (msec)   : 2=0.01%, 4=0.03%, 10=0.17%, 20=0.83%, 50=6.00%
  lat (msec)   : 100=15.48%, 250=43.58%, 500=25.27%, 750=6.38%, 1000=1.31%
  lat (msec)   : 2000=0.71%, >=2000=0.24%
  cpu          : usr=0.38%, sys=2.65%, ctx=240149, majf=0, minf=72
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued rwt: total=262144,0,0, short=0,0,0, dropped=0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=64

Run status group 0 (all jobs):
   READ: bw=1071KiB/s (1096kB/s), 1071KiB/s-1071KiB/s (1096kB/s-1096kB/s), io=1024MiB (1074MB), run=979315-979315msec

Disk stats (read/write):
  sda: ios=259355/10, merge=2705/0, ticks=62083410/1783, in_queue=61955109, util=31.08%

隨機寫

[root@luoahong ~]# fio -name=randwrite -direct=1 -iodepth=64 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sda
randwrite: (g=0): rw=randwrite, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=64
fio-3.1
Starting 1 process
Jobs: 1 (f=1): [w(1)][100.0%][r=0KiB/s,w=1297KiB/s][r=0,w=324 IOPS][eta 00m:00s]
randwrite: (groupid=0, jobs=1): err= 0: pid=10321: Wed Sep  4 10:57:01 2019
  write: IOPS=229, BW=919KiB/s (941kB/s)(898MiB/1000356msec)
    slat (nsec): min=1569, max=151439k, avg=86390.77, stdev=641299.23
    clat (usec): min=139, max=1949.7k, avg=278515.95, stdev=184461.72
     lat (usec): min=1589, max=1949.7k, avg=278603.35, stdev=184431.97
    clat percentiles (msec):
     |  1.00th=[    6],  5.00th=[   16], 10.00th=[  115], 20.00th=[  161],
     | 30.00th=[  192], 40.00th=[  222], 50.00th=[  249], 60.00th=[  279],
     | 70.00th=[  313], 80.00th=[  355], 90.00th=[  443], 95.00th=[  693],
     | 99.00th=[  978], 99.50th=[ 1053], 99.90th=[ 1267], 99.95th=[ 1385],
     | 99.99th=[ 1603]
   bw (  KiB/s): min=    7, max= 2272, per=100.00%, avg=943.44, stdev=339.01, samples=1945
   iops        : min=    1, max=  568, avg=235.59, stdev=84.83, samples=1945
  lat (usec)   : 250=0.01%, 1000=0.01%
  lat (msec)   : 2=0.01%, 4=0.24%, 10=2.62%, 20=3.00%, 50=1.09%
  lat (msec)   : 100=1.28%, 250=42.03%, 500=42.14%, 750=3.40%, 1000=3.38%
  lat (msec)   : 2000=0.82%
  cpu          : usr=0.15%, sys=2.95%, ctx=132790, majf=0, minf=10
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued rwt: total=0,229790,0, short=0,0,0, dropped=0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=64

Run status group 0 (all jobs):
  WRITE: bw=919KiB/s (941kB/s), 919KiB/s-919KiB/s (941kB/s-941kB/s), io=898MiB (941MB), run=1000356-1000356msec

Disk stats (read/write):
  sda: ios=40/229428, merge=0/336, ticks=64/63397222, in_queue=63282052, util=19.13%

順序讀

root@luoahong:~# fio -name=read -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sda
read: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=64
fio-3.1
Starting 1 process
Jobs: 1 (f=1): [R(1)][100.0%][r=8513KiB/s,w=0KiB/s][r=2128,w=0 IOPS][eta 00m:00s]
read: (groupid=0, jobs=1): err= 0: pid=18581: Wed Sep  4 11:52:49 2019
   read: IOPS=2327, BW=9308KiB/s (9531kB/s)(1024MiB/112653msec)
    slat (nsec): min=936, max=139761k, avg=414996.94, stdev=453643.64
    clat (usec): min=379, max=192111, avg=27075.92, stdev=5001.29
     lat (usec): min=806, max=192113, avg=27492.07, stdev=5029.24
    clat percentiles (msec):
     |  1.00th=[   14],  5.00th=[   24], 10.00th=[   25], 20.00th=[   26],
     | 30.00th=[   27], 40.00th=[   27], 50.00th=[   28], 60.00th=[   28],
     | 70.00th=[   28], 80.00th=[   29], 90.00th=[   30], 95.00th=[   31],
     | 99.00th=[   36], 99.50th=[   41], 99.90th=[   91], 99.95th=[  117],
     | 99.99th=[  182]
   bw (  KiB/s): min= 6568, max=10376, per=99.81%, avg=9290.73, stdev=550.37, samples=225
   iops        : min= 1642, max= 2594, avg=2322.52, stdev=137.64, samples=225
  lat (usec)   : 500=0.01%, 1000=0.01%
  lat (msec)   : 2=0.01%, 4=0.01%, 10=0.46%, 20=2.02%, 50=97.24%
  lat (msec)   : 100=0.18%, 250=0.07%
  cpu          : usr=0.17%, sys=95.02%, ctx=44147, majf=0, minf=75
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued rwt: total=262144,0,0, short=0,0,0, dropped=0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=64

Run status group 0 (all jobs):
   READ: bw=9308KiB/s (9531kB/s), 9308KiB/s-9308KiB/s (9531kB/s-9531kB/s), io=1024MiB (1074MB), run=112653-112653msec

Disk stats (read/write):
  sda: ios=256744/7, merge=5167/7, ticks=245516/60, in_queue=245476, util=99.13%
root@luoahong:~# [root@luoahong ~]# fio -name=randwrite -direct=1 -iodepth=64 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sda
iB/1000356msec)
    slat (nsec): min=1569, max=151439k, avg=86390.77, stdev=641299.23
    clat (usec): min=139, max=1949.7k, avg=278515.95, stdev=184461.72
     lat (usec): min=1589, max=1949.7k, avg=278603.35, stdev=184431.97
    clat percentiles (msec):
     |  1.00th=[    6],  5.00th=[   16], 10.00th=[  115], 20.00th=[  161],
     | 30.00th=[  192], 40.00th=[  222], 50.00th=[  249], 60.00th=[  279],
     | 70.00th=[  313], 80.00th=[  355], 90.00th=[  443], 95.00th=[  693],
     | 99.00th=[  978], 99.50th=[ 1053], 99.90th=[ 1267], 99.95th=[ 1385],
     | 99.99th=[ 1603]
   bw (  KiB/s): min=    7, max= 2272, per=100.00%, avg=943.44, stdev=339.01, samples=1945
   iops        : min=    1, max=  568, avg=235.59, stdev=84.83, samples=1945
  lat (usec)   : 250=0.01%, 1000=0.01%
  lat (msec)   : 2=0.01%, 4=0.24%, 10=2.62%, 20=3.00%, 50=1.09%
  lat (msec)   : 100=1.28%, 250=42.03%, 500=42.14%, 750=3.40%, 1000=3.38%
  lat (msec)   : 2000=0.82%
  cpu          : usr=0.15%, sys=2.95%, ctx=132790, majf=0, minf=10
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued rwt: total=0,229790,0, short=0,0,0, dropped=0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=64

Run status group 0 (all jobs):
  WRITE: bw=919KiB/s (941kB/s), 919KiB/s-919KiB/s (941kB/s-941kB/s), io=898MiB (941MB), run=1000356-1000356msec

Disk stats (read/write):
  sda: ios=40/229428, merge=0/336, ticks=64/63397222, in_queue=63282052, util=19.13%

順序寫

root@luoahong:~# fio -name=write -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sda
write: (g=0): rw=write, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=64
fio-3.1
Starting 1 process
Jobs: 1 (f=1): [W(1)][100.0%][r=0KiB/s,w=9228KiB/s][r=0,w=2307 IOPS][eta 00m:00s]
write: (groupid=0, jobs=1): err= 0: pid=18719: Wed Sep  4 11:56:27 2019
  write: IOPS=2123, BW=8492KiB/s (8696kB/s)(1024MiB/123478msec)
    slat (nsec): min=1087, max=170478k, avg=441588.53, stdev=1042972.32
    clat (usec): min=394, max=370796, avg=29695.38, stdev=13215.53
     lat (usec): min=1161, max=371439, avg=30138.96, stdev=13315.57
    clat percentiles (msec):
     |  1.00th=[   11],  5.00th=[   21], 10.00th=[   25], 20.00th=[   27],
     | 30.00th=[   27], 40.00th=[   28], 50.00th=[   28], 60.00th=[   29],
     | 70.00th=[   30], 80.00th=[   32], 90.00th=[   35], 95.00th=[   41],
     | 99.00th=[   69], 99.50th=[  107], 99.90th=[  213], 99.95th=[  292],
     | 99.99th=[  326]
   bw (  KiB/s): min= 2431, max=11952, per=99.70%, avg=8466.10, stdev=1311.50, samples=246
   iops        : min=  607, max= 2988, avg=2116.33, stdev=327.89, samples=246
  lat (usec)   : 500=0.01%
  lat (msec)   : 2=0.01%, 4=0.06%, 10=0.90%, 20=3.49%, 50=93.49%
  lat (msec)   : 100=1.51%, 250=0.46%, 500=0.07%
  cpu          : usr=0.17%, sys=92.34%, ctx=42648, majf=0, minf=12
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued rwt: total=0,262144,0, short=0,0,0, dropped=0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=64

Run status group 0 (all jobs):
  WRITE: bw=8492KiB/s (8696kB/s), 8492KiB/s-8492KiB/s (8696kB/s-8696kB/s), io=1024MiB (1074MB), run=123478-123478msec

Disk stats (read/write):
  sda: ios=62/251952, merge=0/10003, ticks=76/452756, in_queue=452736, util=98.83%

二、在這其中,有幾個參數須要你重點關注一下

direct

iodepth

rw

ioengine

bs

filename

三、下面就是我使用 fio 測試順序讀的一個報告示例。

read: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=64
fio-3.1
Starting 1 process
Jobs: 1 (f=1): [R(1)][100.0%][r=16.7MiB/s,w=0KiB/s][r=4280,w=0 IOPS][eta 00m:00s]
read: (groupid=0, jobs=1): err= 0: pid=17966: Sun Dec 30 08:31:48 2018
   read: IOPS=4257, BW=16.6MiB/s (17.4MB/s)(1024MiB/61568msec)
    slat (usec): min=2, max=2566, avg= 4.29, stdev=21.76
    clat (usec): min=228, max=407360, avg=15024.30, stdev=20524.39
     lat (usec): min=243, max=407363, avg=15029.12, stdev=20524.26
    clat percentiles (usec):
     |  1.00th=[   498],  5.00th=[  1020], 10.00th=[  1319], 20.00th=[  1713],
     | 30.00th=[  1991], 40.00th=[  2212], 50.00th=[  2540], 60.00th=[  2933],
     | 70.00th=[  5407], 80.00th=[ 44303], 90.00th=[ 45351], 95.00th=[ 45876],
     | 99.00th=[ 46924], 99.50th=[ 46924], 99.90th=[ 48497], 99.95th=[ 49021],
     | 99.99th=[404751]
   bw (  KiB/s): min= 8208, max=18832, per=99.85%, avg=17005.35, stdev=998.94, samples=123
   iops        : min= 2052, max= 4708, avg=4251.30, stdev=249.74, samples=123
  lat (usec)   : 250=0.01%, 500=1.03%, 750=1.69%, 1000=2.07%
  lat (msec)   : 2=25.64%, 4=37.58%, 10=2.08%, 20=0.02%, 50=29.86%
  lat (msec)   : 100=0.01%, 500=0.02%
  cpu          : usr=1.02%, sys=2.97%, ctx=33312, majf=0, minf=75
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued rwt: total=262144,0,0, short=0,0,0, dropped=0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=64

Run status group 0 (all jobs):
   READ: bw=16.6MiB/s (17.4MB/s), 16.6MiB/s-16.6MiB/s (17.4MB/s-17.4MB/s), io=1024MiB (1074MB), run=61568-61568msec

Disk stats (read/write):
  sdb: ios=261897/0, merge=0/0, ticks=3912108/0, in_queue=3474336, util=90.09% 

這個報告中,須要咱們重點關注的是, slat、clat、lat ,以及 bw 和 iops 這幾行。工具

先來看剛剛提到的前三個參數。事實上,slat、clat、lat 都是指 I/O 延遲(latency)。不一樣之處在於:

 這裏須要注意的是:

 bw

 iops

四、怎麼才能精確模擬應用程序的 I/O 模式呢?

一般狀況下,應用程序的 I/O 都是讀寫並行的,並且每次的 I/O 大小也不必定相同。因此,剛剛說的這幾種場景,並不能精確模擬應用程序的 I/O 模式。那怎麼才能精確模擬應用程序的 I/O 模式呢?

幸運的是,fio 支持 I/O 的重放。藉助前面提到過的 blktrace,再配合上 fio,就能夠實現對應用程序 I/O 模式的基準測試。你須要先用 blktrace ,記錄磁盤設備的 I/O 訪問狀況;而後使用 fio ,重放 blktrace 的記錄。

好比你能夠運行下面的命令來操做:

# 使用 blktrace 跟蹤磁盤 I/O,注意指定應用程序正在操做的磁盤
$ blktrace /dev/sdb

# 查看 blktrace 記錄的結果
# ls
sdb.blktrace.0  sdb.blktrace.1

# 將結果轉化爲二進制文件
$ blkparse sdb -d sdb.bin

# 使用 fio 重放日誌
$ fio --name=replay --filename=/dev/sdb --direct=1 --read_iolog=sdb.bin 

實驗命令以下

root@luoahong:/opt# blktrace /dev/sda
^C=== sda ===
  CPU  0:                58750 events,     2754 KiB data
  CPU  1:                30543 events,     1432 KiB data
  Total:                 89293 events (dropped 0),     4186 KiB data
root@luoahong:/opt#ls 
sda.blktrace.0  sda.blktrace.1
root@luoahong:/opt#blkparse sda -d sdb.bin
root@luoahong:/opt# ls
sda.blktrace.0  sda.blktrace.1  sdb.bin
root@luoahong:/opt# fio --name=replay --filename=/dev/sda --direct=1 --read_iolog=sda.bin 
......
  8,0    0        0   760.074846448     0  m   N cfq schedule dispatch
  8,0    0    17700   760.075924831   442  A FWFS 80191616 + 8 <- (8,2) 80187520
  8,0    0    17701   760.075997189   442  Q  WS 80191616 + 8 [jbd2/sda2-8]
  8,0    0    17702   760.076071782   442  G  WS 80191616 + 8 [jbd2/sda2-8]
  8,0    0    17703   760.076139949   442  I  WS 80191616 + 8 [jbd2/sda2-8]
  8,0    0        0   760.076208396     0  m   N cfq442SN insert_request
  8,0    0        0   760.076741162     0  m   N cfq442SN Not idling. st->count:1
  8,0    0        0   760.076807933     0  m   N cfq442SN dispatch_insert
  8,0    0        0   760.076875821     0  m   N cfq442SN dispatched a request
  8,0    0        0   760.076943150     0  m   N cfq442SN activate rq, drv=1
  8,0    0    17704   760.077009082   442  D  WS 80191616 + 8 [jbd2/sda2-8]
  8,0    0    17705   760.077959513   442  C  WS 80191616 + 8 [0]
  8,0    0        0   760.078169323     0  m   N cfq442SN complete rqnoidle 1
  8,0    0        0   760.078567431     0  m   N cfq442SN Not idling. st->count:1
  8,0    0        0   760.078638671     0  m   N cfq schedule dispatch
CPU0 (sda):
 Reads Queued:          49,      348KiB	 Writes Queued:        1630,     1862MiB
 Read Dispatches:       48,      344KiB	 Write Dispatches:     2265,     1889MiB
 Reads Requeued:         0		 Writes Requeued:         0
 Reads Completed:       49,      348KiB	 Writes Completed:     2245,     1863MiB
 Read Merges:            0,        0KiB	 Write Merges:          280,     5688KiB
 Read depth:            15        	 Write depth:            33
 PC Reads Queued:        0,        0KiB	 PC Writes Queued:        0,        0KiB
 PC Read Disp.:          0,        0KiB	 PC Write Disp.:          0,        0KiB
 PC Reads Req.:          0		 PC Writes Req.:          0
 PC Reads Compl.:        1		 PC Writes Compl.:        0
 IO unplugs:          1972        	 Timer unplugs:          15
CPU1 (sda):
 Reads Queued:           3,       12KiB	 Writes Queued:        1757,     1871MiB
 Read Dispatches:        4,       16KiB	 Write Dispatches:     2096,     1844MiB
 Reads Requeued:         0		 Writes Requeued:         0
 Reads Completed:        3,       12KiB	 Writes Completed:     2116,     1870MiB
 Read Merges:            0,        0KiB	 Write Merges:          535,     7248KiB
 Read depth:            15        	 Write depth:            33
 PC Reads Queued:        0,        0KiB	 PC Writes Queued:        0,        0KiB
 PC Read Disp.:          1,        0KiB	 PC Write Disp.:          0,        0KiB
 PC Reads Req.:          0		 PC Writes Req.:          0
 PC Reads Compl.:        0		 PC Writes Compl.:        0
 IO unplugs:          1907        	 Timer unplugs:          13

Total (sda):
 Reads Queued:          52,      360KiB	 Writes Queued:        3387,     3734MiB
 Read Dispatches:       52,      360KiB	 Write Dispatches:     4361,     3734MiB
 Reads Requeued:         0		 Writes Requeued:         0
 Reads Completed:       52,      360KiB	 Writes Completed:     4361,     3734MiB
 Read Merges:            0,        0KiB	 Write Merges:          815,    12936KiB
 PC Reads Queued:        0,        0KiB	 PC Writes Queued:        0,        0KiB
 PC Read Disp.:          1,        0KiB	 PC Write Disp.:          0,        0KiB
 PC Reads Req.:          0		 PC Writes Req.:          0
 PC Reads Compl.:        1		 PC Writes Compl.:        0
 IO unplugs:          3879        	 Timer unplugs:          28

Throughput (R/W): 0KiB/s / 4913KiB/s
Events (sda): 68763 entries
Skips: 0 forward (0 -   0.0%)

3、I/O 性能優化

獲得 I/O 基準測試報告後,再用上咱們上一節總結的性能分析套路,找出 I/O 的性能瓶頸並優化,就是水到渠成的事情了。固然, 想要優化 I/O 性能,確定離不開 Linux 系統的
I/O 棧圖的思路輔助。你能夠結合下面的 I/O 棧圖再回顧一下。

下面,我就帶你從應用程序、文件系統以及磁盤角度,分別看看 I/O 性能優化的基本思路。

4、應用程序優化

首先,咱們來看一下,從應用程序的角度有哪些優化 I/O 的思路。

應用程序處於整個 I/O 棧的最上端,它能夠經過系統調用,來調整 I/O 模式(如順序仍是隨機、同步仍是異步), 同時,它也是 I/O 數據的最終來源。在我看來,能夠有這麼幾種
方式來優化應用程序的 I/O 性能。

第一:

第二:

第三:

能夠在應用程序內部構建本身的緩存,或者用 Redis 這類外部緩存系統

 案例

第四:

第五:

第六:

第七:

在使用 CFQ 調度器時

 ionice 支持三個優先級類

 5、文件系統優化

一、你能夠根據實際負載場景的不一樣,選擇最適合的文件系統

二、在選好文件系統後,還能夠進一步優化文件系統的配置選項

三、能夠優化文件系統的緩存

一、你能夠優化 pdflush 髒頁的刷新頻率

二、髒頁的限額

三、優化內核回收目錄項緩存和索引節點緩存的傾向

四、在不須要持久化時,你還能夠用內存文件系統 tmpfs

 6、磁盤優化

數據的持久化存儲,最終仍是要落到具體的物理磁盤中,同時,磁盤也是整個 I/O 棧的最底層。從磁盤角度出發,天然也有不少有效的性能優化方法

一、最簡單有效的優化方法,就是換用性能更好的磁盤

二、咱們可使用 RAID

三、針對磁盤和應用程序 I/O 模式的特徵,咱們能夠選擇最適合的 I/O 調度算法

四、咱們能夠對應用程序的數據,進行磁盤級別的隔離

五、在順序讀比較多的場景中、咱們能夠增大磁盤的預讀數據

調整 /dev/sdb 的預讀大小的兩種方法

調整內核選項

使用 blockdev 工具設置

六、優化內核塊設備 I/O 的選項

七、磁盤自己出現硬件錯誤

 案例

7、小結

今天,咱們一塊兒梳理了常見的文件系統和磁盤 I/O 的性能優化思路和方法。發現 I/O 性能問題後,不要急於動手優化,而要先找出最重要的、能夠最大程度提高性能的問題,而後
再從 I/O 棧的不一樣層入手,考慮具體的優化方法。

記住,磁盤和文件系統的 I/O ,一般是整個系統中最慢的一個模塊。因此,在優化 I/O 問題時,除了能夠優化 I/O 的執行流程,還能夠藉助更快的內存、網絡、CPU 等,減小 I/O調用。

好比,你能夠充分利用系統提供的 Buffer、Cache ,或是應用程序內部緩存, 再或者Redis 這類的外部緩存系統。

相關文章
相關標籤/搜索