nr_requests 以及 queue_depth的學習與瞭解
背景
馮諾依曼的計算機體系結果裏面
運算器,存儲器是核心. 但是將核心的產生的結果推送出去的其實是IO
IO雖然不是像運算器和存儲器那麼核心, 但是他的性能不好會嚴重的影響整體的性能響應
前段時間遇到了很多IO相關的問題, 這一塊學習不是很徹底,
只是在一個週末學習了 IOWAIT和 %busy 等的概念.
想着趁着項目間隙, 學習一下內核裏面關於IO的一兩個核心參數.
太多了記不住. 也沒有實際意義.
回顧
IOWAIT 理解應該是用戶態IO開始到獲得IO的整體時間. 他不僅包含了IO處理的時間SVCTIME 還包含了隊列內的時間.
SVCTIME 是IO設備處理時間. 他主要是依靠設備的能力, 比如IOPS,吞吐量,以及尋址響應時間等.
一個IO的處理時間核心就是這兩處. SVCTIME 內核應該沒法控制, 是驅動連接具體的外設來處理.
隊列的時間其實要看設備支持的隊列情況, 如果硬盤支持多隊列, 但是操作系統只有一個隊列,那麼就會浪費性能.
%busy: busy的參數隨着最近幾年的計算機的迅猛發展其實已經沒有了他本來的意義.
計算模式是 隊列中有IO操作的時間/抽樣的實際時間.
因爲多對列的出現. 和隊列深度的發展. 有任務不一定性能差, 沒任務不一定性能好.
關於nr_requests的理解
這兩個參數其實不是 /proc下的內核參數
還是/sys下面的block設備的參數.
第一個nr_requests的參數爲之一般爲
/sys/block/sda/queue/nr_requests
注意sda 爲 設備名稱 很多虛擬機一般是 vda
很多linux 默認的 隊列數 512
需要注意 這個隊列的含義是隊列的數量.
之前的AHCI 接口硬盤一般只允許一個隊列
隊列深度爲 32
最新的NVME的接口硬盤一般支持 64k個隊列
每個隊列支持的深度爲 64k
更多的隊列會帶來性能的提升. 但是隊列多了對CPU資源和內存資源都有更高的要求.
欲戴王冠必承其重.
關於queue_depth的理解
一般queue_depth與nr_requests不在一個路徑下面
nr_requests 是在 queue 目錄下面
但是 queue_depth 其實是在 device 目錄下面.
也就是說 隊列的數量 其實是 隊列的屬性
隊列的深度, 更像是設備的屬性.
設備支持的深度的情況.
很多linux 發行版默認的數值是 1014
cat /sys/block/sda/device/queue_depth
如果設備有餘力可以適當改大這個參數. 能夠更好的實現性能.
隊列數量與隊列深度的關係
隊列數量是有多少IO操作在排隊.
隊列深度是硬件可以支持多少IO操作同時執行.
因爲隊列有寫隊列和讀隊列, 所以所有的IO隊列應該是 2*nr_requests
隊列深度就是真正發給設備的IO操作. 他可以體現硬件的併發能力.
最早的HDD 支持一個隊列, 隊列深度是32. 就是說排隊的需要少.
一次最多可以並行執行32個IO操作. 這是磁盤電梯算法的極限了.
現階段SSD 已經沒有磁頭和步進電機的物理設備. 使用NVME的協議後他的隊列數量已經得到了巨大的提升.
其他理解
之前IO的調度有很多算法像是 deadline 後者是 cfq 算法.
但是隨着SSD設備的到來 最好的調度據說是noop
理論上計算IO需要使用不同的隊列深度, 隊列已經IO調度算法進行處理.
有時候可以在生產環境上面使用 biohist 等ebpf命令獲取IO 的block的大小.
然後針對性的調整系統內核參數. 調度算法.
然後使用FIO等工具進行壓測, 獲取最好的性能結果.