iostat命令详解_对iostat输出结果的理解
前言:
日常工作中,線上服務會出現各種奇奇怪怪的問題,每次出現問題都是根據現象猜測出現問題的原因,比如請求響應慢了,就排查整個請求的邏輯,每一步花了多少時間,分析半天終于發現是某一步慢了以后,在分析為什么慢。用這樣的方式排查問題效率很低,而且很容易查錯方向,導致不能及時解決問題。直到有一天,一位前輩指點道:出現問題不知道怎么回事,查看系統監控啊。。。這才恍然大悟。
于是我就想整理一下,有哪些值得關注的系統監控可以查看。這個帖子linux系統監控命令匯總給了我思路,可以從內存、cpu、硬盤、網絡,四個方面對系統進行監控。于是我開始整理相關的命令,然后到了磁盤io的時候,查到了iostat命令。在這個帖子IO實時監控命令iostat詳解中介紹iostat -x 輸出的內容里,有一個avgqu-sz 是平均請求隊列的長度。并且說,隊列長度越短越好。然后我就不禁好奇,這個隊列是什么呢?操作系統處理磁盤io的模型是什么呢?于是展開了這次學習之旅。
正文:
這次學習首先發現了之前的一些理解上的偏差,就是用戶態和內核態和阻塞的關系:
用戶態中進程執行read()方法,因為cpu的運算速度遠大于磁盤的尋址速度,所以這個操作是阻塞的。之前我錯誤的理解是,用戶進程執行read()方法,會導致進程阻塞,所以接下來會進入另一個進程,同時因為是系統調用,所以會進入內核態,所以,我理所當然的認為,內核態也是一個進程,比如有n個進程都調用read方法,這個時候內核進程就會把這些io請求放到一個隊列里去調度。正好跟iostat中的隊列相對應。
然鵝,這個觀點是及其錯誤的,用戶態和內核態是一個進程的兩種狀態,兩種狀態的區別是權限級別不一樣,所以用戶態進程執行read()方法,并不會發生上下文切換,只是改變了進程的特權等級。
那么問題就來了,進程什么時候阻塞的?隊列又在哪里呢?后來就看到了這個帖子read系統調用深度剖析里邊講到,read內核態的操作是在不同層上處理的,比如我們要read()a.txt,表面上看,這是讀取一個文件,算一個read請求,但是實際上,這個a.txt只是vfs的抽象出的概念,底層具體文件系統一直到設備驅動層,有可能就變成了對多個扇區的訪問。所以iostat監控的請求數量,并不是我們進程中執行read的數量,而是具體對磁盤扇區操作請求的數量。
接下來的問題就是,隊列在哪里呢?比如有n個進程都要讀寫磁盤,這些進程會在一個隊列里邊排隊,一個一個執行嗎?這個邏輯明顯是有漏洞的,如果一個進程讀很大的文件,豈不是要把其他進程餓死。還好,發現了這個帖子CFQ完全公平隊列,里邊講到,目前內核中默認的調度算法應該是cfq,叫做完全公平隊列調度。這個調度算法人如其名,它試圖給所有進程提供一個完全公平的IO操作環境。它為每個進程創建一個同步IO調度隊列,并默認以時間片和請求數限定的方式分配IO資源。也就是說,對于每個進程的多個io操作,都會放到一個隊列中。io調度層根據時間片調度這些請求。當某一個時間片該進程的數據讀取完成了,方法返回,如果時間片內沒有讀取完,進程進入阻塞。
所以所謂的阻塞的系統調用,并不是調用后立刻就進入阻塞狀態,而是進入內核態以后,在特定的條件下把進程阻塞掉。所以也就有了非阻塞的io調用,在自己的時間片內執行不完io操作,不進入阻塞而是直接返回失敗。下次再調用的時候再執行一部分io操作,直到某一次調用把數據讀取完了,返回成功。
另一個疑問是,文章提到:當設備完成了 IO 請求之后,通過中斷的方式通知 cpu,比如某個進程將請求加入自己的隊列以后,把隊列中相鄰的請求優化掉,然后對磁盤發起讀請求,這個時候后續的讀操作到底需不需要cpu參與呢?如果需要的話,感覺就不需要中斷通知了。如果不需要的話,磁盤自己能把數據寫入內存嗎?
然后就查到了這個:硬盤屬于外儲存器,CPU只能直接讀取內儲存器,如果cpu只能讀取內存的話,隊列中對于磁盤扇區到讀寫操作就不會占用cpu資源。但是數據到達內存以后,復制到用戶空間需要cpu參與,所以大量文件到讀寫還是會占用cpu資源。
總結一下,iostat有兩個數據監控,一個是cpu,一個是硬盤,之所以這么設計,我的理解是把io操作分為了需要cpu和不需要cpu的兩個階段,可以針對兩個階段的監控信息分別分析問題,比如,如果硬盤監控的%util接近100%,說明磁盤一直在讀寫扇區,這個時候硬盤是瓶頸。如果硬盤正常,cpu彪高,說明大量內存的讀寫占用了大量cpu,這時cpu是瓶頸。
另外,因為cfq隊列對每個進程都維護一個隊列,所以iostat中avgqu-sz 是平均請求隊列的長度,是所有隊列的平均值。
補充一點的話,還看到這么個說法:
傳統磁盤本質上一種機械裝置,如FC,SAS,SATA磁盤,轉速通常為5400/7200/10K/15K rpm不等。影響磁盤的關鍵因素是磁盤服務時間,即磁盤完成一個I/O請求所花費的時間,它由尋道時間、旋轉延遲和數據傳輸時間三部分構成。尋道時間Tseek是指將讀寫磁頭移動至正確的磁道上所需要的時間。尋道時間越短,I/O操作越快,目前磁盤的平均尋道時間一般在3-15ms。旋轉延遲Trotation是指盤片旋轉將請求數據所在扇區移至讀寫磁頭下方所需要的時間。旋轉延遲取決于磁盤轉速,通常使用磁盤旋轉一周所需時間的1/2表示。比如,7200 rpm的磁盤平均旋轉延遲大約為60*1000/7200/2 = 4.17ms,而轉速為15000 rpm的磁盤其平均旋轉延遲約為2ms。數據傳輸時間Ttransfer是指完成傳輸所請求的數據所需要的時間,它取決于數據傳輸率,其值等于數據大小除以數據傳輸率。目前IDE/ATA能達到133MB/s,SATA II可達到300MB/s的接口數據傳輸率,數據傳輸時間通常遠小于前兩部分時間。因此,理論上可以計算出磁盤的最大IOPS,即IOPS = 1000 ms/ (Tseek + Troatation),忽略數據傳輸時間。假設磁盤平均物理尋道時間為3ms, 磁盤轉速為7200,10K,15K rpm,則磁盤IOPS理論最大值分別為,IOPS = 1000 / (3 + 60000/7200/2) = 140IOPS = 1000 / (3 + 60000/10000/2) = 167IOPS = 1000 / (3 + 60000/15000/2) = 200也就是說,磁盤瓶頸的本質是轉速,10K的硬盤,每秒最多處理167個請求,如果iostat監控發現r/s超過了167,肯定會導致%util 100%以及很高的await,所以硬盤的瓶頸是請求次數。而cpu的瓶頸是訪問的數據量,因為越大的數據量就需要越多的指令去復制拷貝。
總結:
最開始分析內存監控的時候,發現了cache和buffer區的概念,對磁盤的操作會把磁盤數據緩存到cache中,也就是說如果寫一個測試用例不停的讀寫同一個文件,看監控并不會發現%util有變化,因為都是對內存的操作。
附錄:
linux磁盤io調度算法:linux IO調度算法
最后,讓我們保持獨立思考,不卑不亢。長成自己想要的樣子!
(引用自 我非常喜歡的B站up主 ”獨立菌兒“的口頭禪嗶哩嗶哩 ( ゜- ゜)つロ 乾杯~ Bilibili)
總結
以上是生活随笔為你收集整理的iostat命令详解_对iostat输出结果的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bootstraptable中respo
- 下一篇: 2000坐标系高程与85高程转换_【科普