Linux性能優化之磁盤優化(三)


前言

關於本章內容,設計的東西比較多。這里會有關於文件系統、磁盤、CPU等方面的知識,以及涉及到關於這方面的性能排查等。

術語

文件系統通過緩存和緩沖以及異步I/O等手段來緩和磁盤的延時對應用程序的影響。為了更詳細的了解文件系統,以下就簡單介紹一些相關術語:

  • 文件系統:一種把數據組織成文件和目錄的存儲方式,提供了基於文件的存取接口,並通過文件權限控制訪問。另外,一些表示設備、套接字和管道的特殊文件類型,以及包含文件訪問時間戳的元數據。
  • 文件系統緩存:主存(通常是DRAM) 的一塊區域,用來緩存文件系統的內容,可能包含各種數據和元數據。
  • 操作:文件系統的操作是對文件系統的請求,包括讀、寫、打開、關閉、創建以及其他操作。
  • I/O:輸入/輸出。文件系統I/O有多種定義,這里僅指直接讀寫(執行I/O)的操作,包括讀、寫、狀態統計、創建。I/O不包括打開文件和關閉文件。
  • 邏輯I/O:由應用程序發給文件系統的I/O。
  • 物理I/O:由文件系統直接發給磁盤的I/O。
  • 吞吐量:當前應用程序和文件系統之間的數據傳輸率,單位是B/S。
  • inode:一個索引節點時一種含有文件系統對象元數據的數據結構,其中有訪問權限、時間戳以及數據指針。
  • VFS:虛擬文件系統,一個為了抽象與支持不同文件系統類型的內核接口。

磁盤相關術語:

  • 存儲設備的模擬。在系統看來,這是一塊物理磁盤,但是,它可能由多塊磁盤組成。
  • 傳輸總線:用來通信的物理總線,包括數據傳輸以及其他磁盤命令。
  • 扇區:磁盤上的一個存儲塊,通常是512B的大小。
  • I/O:對於磁盤,嚴格地說僅僅指讀、寫,而不包括其他磁盤命令。I/O至少由方向(讀或寫)、磁盤地址(位置)和大小(字節數)組成。
  • 磁盤命令:除了讀寫之外,磁盤還會被指派執行其他非數據傳輸的命令(例如緩存寫回)。
  • 帶寬:存儲傳輸或者控制器能夠達到的最大數據傳輸速率。
  • I/O延時:一個I/O操作的執行時間,這個詞在操作系統領域廣泛使用,早已超出了設備層。

相關概念

  文件系統延時
       文件系統延時是文件系統性能一項主要的指標,指的是一個文件系統邏輯請求從開始到結束的時間。它包括消耗在文件系統、內核磁盤I/O子系統以及等待磁盤設備——物理I/O的時間。應用程序的線程通常在請求時阻塞,等地文件系統請求的結束。這種情況下,文件系統的延時與應用程序的性能直接和成正比關系。在某些情況下,應用程序並不受文件系統的直接影響,例如非阻塞I/O或者I/O由一個異步線程發起。

  緩存

       文件系統啟動之后會使用主存(RAM)當緩存以提供性能。緩存大小隨時間增長而操作系統的空余內存不斷減小,當應用程序需要更多內存時,內核應該迅速從文件系統緩存中釋放一些內存空間。文件系統用緩存(caching)提高讀性能,而用緩沖(buffering)提高寫性能。文件系統和塊設備子系統一般使用多種類型的緩存。

  隨機I/O與順序I/O
        一連串的文件系統邏輯I/O,按照每個I/O的文件偏移量,可以分為隨機I/O與順序I/O。順序I/O里每個I/O都開始於上一個I/O結束的地址。隨機I/O則找不出I/O之間的關系,偏移量隨機變化。隨機的文件系統負載也包括存取隨機的文件。由於存儲設備的某些性能特征的緣故,文件系統一直以來在磁盤上順序和連續的存放文件數據,以努力減小隨機I/O的數目。當文件系統未能達到這個目標時,文件的擺放變得雜亂無章,順序的邏輯I/O被分解成隨機的物理I/O,這種情況被稱為碎片化。

提示:關於文件系統更多內容,還請自行查閱相關理論。比如你還需要了解文件系統的預讀、預取、寫回緩存、同步寫、裸I/O、直接I/O、內存映射文件、元數據等相關知識。

性能分析

具備背景知識是分析性能問題時需要了解的。比如硬件 cache;再比如操作系統內核。應用程序的行為細節往往是和這些東西互相牽扯的,這些底層的東西會以意想不到的方式影響應用程序的性能,比如某些程序無法充分利用 cache,從而導致性能下降。比如不必要地調用過多的系統調用,造成頻繁的內核 / 用戶切換等。如果想深入了解Linux系統,建議購買相關書籍進行系統的學習。下面我們介紹如何分析磁盤性能工具(其實准確來說,不只是磁盤):

iostat

匯總了單個磁盤的統計信息,為磁盤負載、使用率和飽和度提供了指標。默認顯示一行系統總結信息,包括內核版本、主機名、日志、架構和CPU數量等,每個磁盤設備都占一行。

[root@localhost ~]# iostat 
Linux 3.10.0-514.el7.x86_64 (localhost.localdomain) 	2017年09月18日 	_x86_64_	(1 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.74    0.00    1.24    1.35    0.00   96.67

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda              14.43       456.85        60.82     218580      29098
scd0              0.02         0.09         0.00         44          0
dm-0             13.65       404.58        56.50     193571      27030
dm-1              0.27         2.23         0.00       1068          0

參數說明

  • tps: 每秒事物數(IOPS)。
  • kB_read/s、kB_wrtn/s: 每秒讀取KB數和每秒寫入KB數。
  • kB_read、kB_wrtn: 總共讀取和寫入的KB數。

如下想輸出更詳細的內容,可以試試下面這個命令組合:

[root@localhost ~]# iostat -xkdz 1
Linux 3.10.0-514.el7.x86_64 (localhost.localdomain) 	2017年09月18日 	_x86_64_	(1 CPU)

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.01     2.43   13.81    2.32   510.51    67.96    71.74     0.22   13.94    8.72   44.95   2.37   3.82
scd0              0.00     0.00    0.03    0.00     0.10     0.00     8.00     0.00    0.27    0.27    0.00   0.27   0.00
dm-0              0.00     0.00   10.52    4.73   452.10    63.13    67.56     0.44   28.56   10.41   68.93   2.47   3.76
dm-1              0.00     0.00    0.30    0.00     2.49     0.00    16.69     0.00    1.50    1.50    0.00   1.38   0.04

參數說明

  • rrqm/s:每秒合並放入驅動請求隊列的讀請求數(當系統調用需要讀取數據的時候,VFS將請求發到各個FS,如果FS發現不同的讀取請求讀取的是相同Block的數據,FS會將這個請求合並Merge)。
  • wrqm/s:每秒合並放入驅動請求隊列的寫請求數。
  • rsec/s:每秒發給磁盤設備的讀請求數。
  • wsec/:每秒發給磁盤設備的寫請求數。
  • rKB/s:每秒從磁盤設備讀取的KB數。
  • wKB/s:每秒向磁盤設備寫入的KB數。
  • avgrq-sz 平均每次請求大小,單位為扇區(512B)。
  • avgqu-sz 在驅動請求隊列和在設備中活躍的平均請求數。
  • await: 平均I/O響應時間,包括在驅動請求隊列里等待和設備的I/O響應時間(ms)。一般地系統I/O響應時間應該低於5ms,如果大於10ms就比較大了。這個時間包括了隊列時間和服務時間,也就是說,一般情況下,await大於svctm,它們的差值越小,則說明隊列時間越短,反之差值越大,隊列時間越長,說明系統出了問題。
  • svctm:磁盤設備的I/O平均響應時間(ms)。如果svctm的值與await很接近,表示幾乎沒有I/O等待,磁盤性能很好,如果await的值遠高於svctm的值,則表示I/O隊列等待太長系統上運行的應用程序將變慢。
  • %util: 設備忙處理I/O請求的百分比(使用率)。在統計時間內所有處理IO時間,除以總共統計時間。例如,如果統計間隔1秒,該設備有0.8秒在處理IO,而0.2秒閑置,那么該設備的%util = 0.8/1 = 80%,所以該參數暗示了設備的繁忙程度。一般地,如果該參數是100%表示設備已經接近滿負荷運行了(當然如果是多磁盤,即使%util是100%,因為磁盤的並發能力,所以磁盤使用未必就到了瓶頸)。

      既然avgrq-sz是合並之后的數字,小尺寸(16個扇區或者更小)可以視為無法合並的實際I/O負載的跡象。大尺寸有可能是大I/O,或者是合並的連續負載。輸出性能里最重要的指標是await。如果應用程序和文件系統使用了降低寫延時的方法,w_await可能不那么重要,而更應該關注r_await。
      對於資源使用和容量規划,%util仍然很重要,不過記住這只是繁忙度的一個度量(非空閑時間),對於后面有多塊磁盤支持的虛擬設備意義不大。可以通過施加負載更好地了解這些設備:IOPS(r/s + w/s)以及吞吐量(rkB/s + wkB/s)。

iotop

包含磁盤I/O的top工具。

批量模式(-b)可以提供滾動輸出。下面的演示僅僅顯示I/O進程(-o),每5秒輸出一次(-d5):

[root@localhost ~]# iotop -bod5
Total DISK READ :       0.00 B/s | Total DISK WRITE :       8.76 K/s
Actual DISK READ:       0.00 B/s | Actual DISK WRITE:      24.49 K/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN      IO    COMMAND
21203 be/3 root        0.00 B/s  815.58 B/s  0.00 %  0.01 % [jbd2/dm-2-8]
22069 be/3 root        0.00 B/s    0.00 B/s  0.00 %  0.01 % [jbd2/dm-1-8]
 1531 be/0 root        0.00 B/s    6.37 K/s  0.00 %  0.01 % [loop0]
 3142 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.01 % [kworker/7:0]
21246 be/4 root        0.00 B/s 1631.15 B/s  0.00 %  0.00 % java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs=/usr/local/tomcat/endorsed -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start

提示:

        輸出顯示java進程正在以大約1631.15 B/s的速率施加磁盤寫負載。其他有用的選項有-a,可以輸出累計I/O而不是一段時間內的平均值,選項-o,只打印那些正在執行的磁盤I/O的進程。

  當然顯示磁盤的命令還有例如sar、iosnoop、perf、blktrace等命令,這里只列舉常用命令即可。

性能調優

文件系統優化

關於文件系統優化,並沒有太多的內容需要說明。就目前的情況,Redhat Enterprise 7系列默認更換為性能更好的XFS,這也是由於XFS在性能表現確實很好的原因。在我們使用的過程中,建議對XFS做一些簡單的優化即可,比如執行格式化時指定額外的一些參數,掛載該分區時指定一些額外的掛載參數,這些都能夠提高文件系統的相關性能。

格式化時的參數:

mkfs.xfs -d agcount=256 -l size=128m,lazy-count=1,version=2 /dev/diska1

mount時的參數:

defaults,noatime,nodiratime,nobarrier,discard,allocsize=256m,logbufs=8,attr2,logbsize=256k

磁盤相關優化

  • 操作系統可調參數

  包括ionice、資源控制和內核可調參數。

  ionice

  Linux中的ionice命令可以設置一個進程I/O調度級別和優先級。調度級別為整數,0表示無,不指定級別,內核會挑選一個默認值,優先級根據進程nice值選定;1表示實時,對磁盤的最高級別訪問,如果誤用會導致其他進程餓死;2表示盡力,默認調度級別,包括優先級 0~7,0為最高級;3表示空閑,在一段磁盤空閑的期限過后才允許進行I/O。如下:

ionice -c 3 -p 65552

    cgroup

  通過cgroup為進程或進程組提供存儲設備資源控制機制。一般很少用到,不用考慮。

    可調參數

  /sys/block/sda/queue/scheduler:選擇I/O調度器策略,是空操作、最后期限、an還是cfq;

  • 磁盤設備可調參數

  Linux上的hdparm(磁盤測試工具)工具可以設置多種磁盤設備的可調參數。

  • 磁盤控制器可調參數

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM