新聞中心
在Linux系統(tǒng)中,進程占用IO的問題是很常見的。當進程占用了過多的IO資源時,會導致系統(tǒng)變慢,甚至崩潰。因此,是非常重要的。本文將介紹常見的解決方法。

專業(yè)成都網站建設公司,做排名好的好網站,排在同行前面,為您帶來客戶和效益!成都創(chuàng)新互聯(lián)公司為您提供成都網站建設,五站合一網站設計制作,服務好的網站設計公司,成都網站制作、做網站負責任的成都網站制作公司!
1. 使用iostat分析IO情況
iostat是一個常用的IO性能分析工具,它可以分析IO吞吐量、IO延遲和IO負載等指標。使用iostat可以幫助我們了解系統(tǒng)的IO使用情況,從而判斷是否存在進程占用IO的問題。
使用iostat需要安裝sysstat包。在Ubuntu系統(tǒng)中,可以通過以下命令安裝:
“`
sudo apt-get update
sudo apt-get install sysstat
“`
安裝完成后,可以使用以下命令查看IO情況:
“`
iostat -x 1
“`
該命令會每隔1秒輸出一次IO情況。可以觀察每個設備的平均IO響應時間(awt)、IO利用率(util)等指標,判斷是否存在進程占用IO的問題。
2. 使用lsof查找占用文件的進程
lsof是一個常用的文件列表命令,可以列出系統(tǒng)中打開的文件和進程信息。使用lsof可以查找哪個進程占用了某個文件或目錄。
例如,以下命令可以查找占用/dev/sda1文件系統(tǒng)的進程:
“`
sudo lsof /dev/sda1
“`
如果該命令返回結果,則說明存在占用/dev/sda1的進程。通過查找占用文件的進程,我們可以定位占用IO資源的進程,從而采取相應的措施。
3. 使用ionice限制進程IO優(yōu)先級
ionice是一個用于限制進程IO優(yōu)先級的工具。使用ionice可以調整進程對IO資源的使用權,從而避免某個進程占用過多的IO資源導致系統(tǒng)變慢。
ionice有三個命令:-c、-n和-p。其中,-c指定調度策略,可以是idle、batch、best-effort或realtime;-n指定IO優(yōu)先級,可以是0到7的整數;-p指定進程ID。
例如,以下命令可以將進程ID為1234的進程的IO優(yōu)先級調整為3:
“`
sudo ionice -c3 -p1234
“`
通過調整進程IO優(yōu)先級,我們可以控制進程對IO資源的使用權,從而避免占用過多的IO資源。
4. 使用cgroups限制進程IO資源
cgroups是Linux內核提供的一種資源限制機制,可以限制進程的CPU、內存、IO等資源使用。使用cgroups可以限制某個進程的IO資源使用,避免進程占用過多的IO資源導致系統(tǒng)變慢。
在Ubuntu系統(tǒng)中,可以通過以下命令安裝cgroups:
“`
sudo apt-get update
sudo apt-get install cgroup-tools
“`
安裝完成后,可以使用以下命令創(chuàng)建一個名為test的cgroup,并限制該cgroup中的進程IO速率為50M/s:
“`
sudo cgcreate -g blkio:test
sudo cgset -r blkio.throttle.read_bps_device=/dev/sda1 50M test
“`
該命令會創(chuàng)建一個名為test的cgroup,并限制該cgroup中的進程在/dev/sda1設備上的讀IO速率為50M/s。如果某個進程被加入到test cgroup,則其IO速率將被限制。
通過使用cgroups,我們可以靈活地限制進程的IO資源使用,從而避免進程占用過多的IO資源導致系統(tǒng)變慢。
是非常重要的。本文介紹了常見的解決方法,包括使用iostat分析IO情況、使用lsof查找占用文件的進程、使用ionice限制進程IO優(yōu)先級和使用cgroups限制進程IO資源。通過采取合適的措施,我們可以避免進程占用過多的IO資源,保證系統(tǒng)的穩(wěn)定性和可靠性。
相關問題拓展閱讀:
- linux查看磁盤io的幾種方法
- 如何提高Linux下塊設備IO的整體性能
linux查看磁盤io的幾種方法
linux查看磁盤io的幾種方法
怎樣才能快速的定位到并發(fā)高是由于磁盤io開銷大呢?可以通過三種方式:
之一種:用 top 命令 中的cpu 信息觀察
Top可以看到的cpu信息有:
Tasks: 29 total, 1 running, 28 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.3% us, 1.0% sy, 0.0% ni, 98.7% id, 0.0% wa, 0.0% hi, 0.0% si
具體的解釋如下:
Tasks: 29 total 進程總數
1 running 正在運行的進程數
28 sleeping 睡眠的進程數
0 stopped 停止的進程數
0 zombie 僵尸進程數
Cpu(s):
0.3% us 用戶空間占用CPU百分比
1.0% sy 內核空間占用CPU百分比
0.0% ni 用戶進程空間內改變過優(yōu)先級的進程占用CPU百分比
98.7% id 空閑CPU百分比
0.0% wa 等待輸入輸出的CPU時間百分比
0.0% hi
0.0% si
0.0% wa 的百分比可以大致的體現(xiàn)出當前的磁盤io請求是否頻繁。如果 wa的數量比較大,說明等待輸入輸出的的io比較多。
第二種:用vmstat
vmstat 命令報告關于線程、
虛擬內存
、磁盤、陷阱和 CPU 活動的統(tǒng)計信息。由 vmstat 命令生成的報告可以用于平衡系統(tǒng)負載活動。系統(tǒng)范圍內的這些統(tǒng)計信息(所有的處理器中)都計算出以百分比表示的
平均值
,或者計算其總和。
輸入命令:
vmstat 2 5
如果發(fā)現(xiàn)等待的進程和處在非中斷睡眠狀態(tài)的進程數非常多,并且發(fā)送到塊設備的塊數和從塊設備接收到的塊數非常大,那就說明磁盤隱緩io比較多。
vmstat參數解釋:
Procs
r: 等待運行的進程數 b: 處在非中斷睡眠狀態(tài)的進程數 w: 被交換出去的可運行的進程慧信數。此數由 linux 計算得出,但 linux 并不耗盡交換空間
Memory
swpd: 虛擬內存使用情況,單位:KB
free: 空閑的內存,單位KB
buff: 被用來做為緩存的內存數,單位:KB
Swap
si: 從磁盤交換到內存的交換頁數量,單位:KB/秒
so: 從內存交換到磁盤的灶碧模交換頁數量,單位:KB/秒
IO
bi: 發(fā)送到塊設備的塊數,單位:塊/秒
bo: 從塊設備接收到的塊數,單位:塊/秒
System
in: 每秒的中斷數,包括時鐘中斷
cs: 每秒的環(huán)境(上下文)切換次數
CPU
按 CPU 的總使用百分比來顯示
us: CPU 使用時間
sy: CPU 系統(tǒng)使用時間
id: 閑置時間
準測
更多vmstat使用信息
第二種:用iostat
安裝:
Iostat 是 sysstat 工具集的一個工具,需要安裝。
Centos的安裝方式是:
yum install sysstat
Ubuntu的安裝方式是:
aptitude install sysstat
使用:
iostat -dx 顯示磁盤擴展信息
root@fileapp:~# iostat -dx
r/s 和 w/s 分別是每秒的讀操作和寫操作,而rKB/s 和wKB/s 列以每秒千字節(jié)為單位顯示了讀和寫的數據量
如果這兩對數據值都很高的話說明磁盤io操作是很頻繁。
+++++++++++++++++++++++++++++++++++++
linux wa%過高,iostat查看io狀況
1, 安裝 iostat
yum install sysstat
之后就可以使用 iostat 命令了,
2,入門使用
iostat -d -k 2
參數 -d 表示,顯示設備(磁盤)使用狀態(tài);-k某些使用block為單位的列強制使用Kilobytes為單位;2表示,數據顯示每隔2秒刷新一次。
tps:該設備每秒的傳輸次數(Indicate the number of transfers per second that were issued to the device.)?!币淮蝹鬏敗币馑际恰币淮蜪/O請求”。多個邏輯請求可能會被合并為”一次I/O請求”?!币淮蝹鬏敗闭埱蟮拇笮∈俏粗?。kB_read/s:每秒從設備(drive expressed)讀取的數據量;
kB_wrtn/s:每秒向設備(drive expressed)寫入的數據量;
kB_read:讀取的總數據量;kB_wrtn:寫入的總數量數據量;這些單位都為Kilobytes。
指定監(jiān)控的設備名稱為sda,該命令的輸出結果和上面命令完全相同。
iostat -d sda 2
默認監(jiān)控所有的硬盤設備,現(xiàn)在指定只監(jiān)控sda。
3, -x 參數
iostat還有一個比較常用的選項 -x ,該選項將用于顯示和io相關的擴展數據。
iostat -d -x -k 1 10
輸出信息的含義
。
4, 常見用法
iostat -d -k#查看TPS和
吞吐量
信息(磁盤讀寫速度單位為KB)
iostat -d -m#查看TPS和吞吐量信息(磁盤讀寫速度單位為MB)
iostat -d -x -k#查看設備使用率(%util)、響應時間(await) iostat -c 1 10 #查看cpu狀態(tài)
5, 實例分析
iostat -d -k 1 | grep vda
Device:tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda60…
sda99…
sda83…
sda18…
sda46…
sda27…
上面看到,磁盤每秒傳輸次數平均約400;每秒磁盤讀取約5MB,寫入約1MB。
iostat -d -x -k 1
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda.56 28.31 7.84 31……..80 2.61 10.29
sda.98 24.75 419.80 6……..70 2.00 85.25
sda.06 41.84 444.90 54……..21 1.85 92.24
可以看到磁盤的平均響應時間80。磁盤響應正常,但是已經很繁忙了。
可以看到磁盤的平均響應時間90。磁盤響應正常,但是已經很繁忙了。
await: 每一個IO請求的處理的平均時間(單位是微秒毫秒)。這里可以理解為IO的響應時間,一般地系統(tǒng)IO響應時間應該低于5ms,如果大于10ms就比較大了
svctm 表示平均每次設備I/O操作的服務時間(以毫秒為單位)。如果svctm的值與await很接近,表示幾乎沒有I/O等待,磁盤性能很好,
如果await的值遠高于svctm的值,則表示I/O隊列等待太長, 系統(tǒng)上運行的
應用程序
將變慢。
%util: 在統(tǒng)計時間內所有處理IO時間,除以總共統(tǒng)計時間
所以該參數暗示了設備的繁忙程度
。一般地,如果該參數是100%表示設備已經接近滿負荷運行了(當然如果是多磁盤,即使%util是100%,因為磁盤的并發(fā)能力,所以磁盤使用未必就到了瓶頸)。
也可以使用下面的命令,同時顯示cpu和磁盤的使用情況
等待時間超過5ms, 磁盤io有問題
如何提高Linux下塊設備IO的整體性能
前言:本文主要講解Linux IO調度層的三種模式:cfp、deadline和noop,并給出各自的優(yōu)化和適用場景建議掘歷。
IO調度發(fā)生在Linux內核的IO調度層。租檔這個層次是針對Linux的整體IO層次體系來說的。從read()或者write()系統(tǒng)調用的角度來說,Linux整體IO體系可以分為七層,它們分別是:
VFS層: 虛擬文件系統(tǒng)層。由于內核要跟多種文件系統(tǒng)打交道,而每一種文件系統(tǒng)所實現(xiàn)的數據結構和相關方法都可能不盡相同,所以,內核抽象了這一層,專門用來適配各種文件系統(tǒng),并對外提供統(tǒng)一操作接口。
文件系統(tǒng)層: 不同的文件系統(tǒng)實現(xiàn)自己的操作過程,提供自己特有的特征,具體不多說了,大家愿意的話自己去看代碼即可。
頁緩存層: 負責真對page的緩存。
通用塊層: 由于絕大多數情況的io操作是跟塊設備打交道,所以Linux在此提供了一個類似vfs層的塊設備操作抽象層。下層對接各種不同屬性的塊設備,對上提供統(tǒng)一的Block IO請求標準。
IO調度層 :因為絕大多數的塊設備都是類似磁盤這樣的設備,所以有必要根據這類設備的特點以及應用的不同特點來設置一些不同的調度算法和隊列。以便在不同的應用環(huán)境下有針對性的提高磁盤的讀寫效率,這里就是大名鼎鼎的Linux電梯所起作用的地方。針對機械硬盤的各種調度方法就是在這實現(xiàn)的。
塊設備驅動層: 驅動層對外提供相對比較高級的設備操作接口,往往是C語言的,而下層對接設備本身的操作方法和規(guī)范。
塊設備層: 這層就是具體的物理設備了,定義了各種真對設備操作方法和規(guī)范。
有一個已經整理好的,非常經典,一圖勝千言:
我們今天要研究的內容主要在IO調度這一層。
它要解決的核心問題是,如何提高塊設備IO的整體性能?這一層也主要是針對機械硬盤結構而設計的。
眾所周知,機械硬盤的存儲介質是磁盤,磁頭在盤片上移動進行磁道尋址,行為類似播放一張唱片。
這種結構的特點是,順序訪問時吞吐量較高,但是如果一旦對盤片有隨機訪問,那么大量的時間都會浪費在磁頭的移動上,這時候就會導致每次IO的響應時間變長,極大的降低IO的響應速度。
磁頭在盤片上尋道的操作,類似電梯調度,實際上在最開始的時期,Linux把這個算法命名為Linux電梯算法,即:
如果在尋道的過程中,能把順序路過的相關磁道的數據請求都“順便”處理掉,那么就可以在比較小影響響應速度的前提下,提高整體IO的吞吐量。
這就是我們?yōu)槭裁匆O計IO調度算法的原因。
目前在內核中默認開啟了三種算法/模式:noop,cfq和deadline。嚴格算應該是兩種:
因為之一種叫做noop,就是空操作調度算法,也就是沒有任何調度操作,并不對io請求進行排序,僅僅做適當的io合并的一個fifo隊列。
目前內核中默認的調度算法應該是cfq,叫做完全公平隊列調度。這個調度算法人如其名,它試圖給所有進程提供一個完全公平的IO操作環(huán)境。
注:請大家一定記住這個詞語,cfq,完全公平隊列調度,不然下文就沒法看了。
cfq為每個進程創(chuàng)建一個同步IO調度隊列,并默認以時間片和請求數限定的方式分配IO資源,以此保證每個進程的IO資源占用是公平的,cfq還實現(xiàn)了針對進程級別的優(yōu)先級調度,這個我們后面會詳細解釋。
查看和修改IO調度算法的方法是:
cfq是通用服務器比較好的IO調度算法選擇,對桌面用戶也是比較好的選擇。
但是對于很多IO壓力較大的場景就并不是判型搜很適應,尤其是IO壓力集中在某些進程上的場景。
因為這種場景我們需要更多的滿足某個或者某幾個進程的IO響應速度,而不是讓所有的進程公平的使用IO,比如數據庫應用。
deadline調度(最終期限調度)就是更適合上述場景的解決方案。deadline實現(xiàn)了四個隊列:
其中兩個分別處理正常read和write,按扇區(qū)號排序,進行正常io的合并處理以提高吞吐量。因為IO請求可能會集中在某些磁盤位置,這樣會導致新來的請求一直被合并,可能會有其他磁盤位置的io請求被餓死。
另外兩個處理超時read和write的隊列,按請求創(chuàng)建時間排序,如果有超時的請求出現(xiàn),就放進這兩個隊列,調度算法保證超時(達到最終期限時間)的隊列中的請求會優(yōu)先被處理,防止請求被餓死。
不久前,內核還是默認標配四種算法,還有一種叫做as的算法(Anticipatory scheduler),預測調度算法。一個高大上的名字,搞得我一度認為Linux內核都會算命了。
結果發(fā)現(xiàn),無非是在基于deadline算法做io調度的之前等一小會時間,如果這段時間內有可以合并的io請求到來,就可以合并處理,提高deadline調度的在順序讀寫情況下的數據吞吐量。
其實這根本不是啥預測,我覺得不如叫撞大運調度算法,當然這種策略在某些特定場景差效果不錯。
但是在大多數場景下,這個調度不僅沒有提高吞吐量,還降低了響應速度,所以內核干脆把它從默認配置里刪除了。畢竟Linux的宗旨是實用,而我們也就不再這個調度算法上多費口舌了。
1、cfq:完全公平隊列調度
cfq是內核默認選擇的IO調度隊列,它在桌面應用場景以及大多數常見應用場景下都是很好的選擇。
如何實現(xiàn)一個所謂的完全公平隊列(Completely Fair Queueing)?
首先我們要理解所謂的公平是對誰的公平?從操作系統(tǒng)的角度來說,產生操作行為的主體都是進程,所以這里的公平是針對每個進程而言的,我們要試圖讓進程可以公平的占用IO資源。
那么如何讓進程公平的占用IO資源?我們需要先理解什么是IO資源。當我們衡量一個IO資源的時候,一般喜歡用的是兩個單位,一個是數據讀寫的帶寬,另一個是數據讀寫的IOPS。
帶寬就是以時間為單位的讀寫數據量,比如,100Mbyte/s。而IOPS是以時間為單位的讀寫次數。在不同的讀寫情境下,這兩個單位的表現(xiàn)可能不一樣,但是可以確定的是,兩個單位的任何一個達到了性能上限,都會成為IO的瓶頸。
從機械硬盤的結構考慮,如果讀寫是順序讀寫,那么IO的表現(xiàn)是可以通過比較少的IOPS達到較大的帶寬,因為可以合并很多IO,也可以通過預讀等方式加速數據讀取效率。
當IO的表現(xiàn)是偏向于隨機讀寫的時候,那么IOPS就會變得更大,IO的請求的合并可能性下降,當每次io請求數據越少的時候,帶寬表現(xiàn)就會越低。
從這里我們可以理解,針對進程的IO資源的主要表現(xiàn)形式有兩個: 進程在單位時間內提交的IO請求個數和進程占用IO的帶寬。
其實無論哪個,都是跟進程分配的IO處理時間長度緊密相關的。
有時業(yè)務可以在較少IOPS的情況下占用較大帶寬,另外一些則可能在較大IOPS的情況下占用較少帶寬,所以對進程占用IO的時間進行調度才是相對最公平的。
即,我不管你是IOPS高還是帶寬占用高,到了時間咱就換下一個進程處理,你愛咋樣咋樣。
所以,cfq就是試圖給所有進程分配等同的塊設備使用的時間片,進程在時間片內,可以將產生的IO請求提交給塊設備進行處理,時間片結束,進程的請求將排進它自己的隊列,等待下次調度的時候進行處理。這就是cfq的基本原理。
當然,現(xiàn)實生活中不可能有真正的“公平”,常見的應用場景下,我們很肯能需要人為的對進程的IO占用進行人為指定優(yōu)先級,這就像對進程的CPU占用設置優(yōu)先級的概念一樣。
所以,除了針對時間片進行公平隊列調度外,cfq還提供了優(yōu)先級支持。每個進程都可以設置一個IO優(yōu)先級,cfq會根據這個優(yōu)先級的設置情況作為調度時的重要參考因素。
優(yōu)先級首先分成三大類:RT、BE、IDLE,它們分別是實時(Real Time)、更佳效果(Best Try)和閑置(Idle)三個類別,對每個類別的IO,cfq都使用不同的策略進行處理。另外,RT和BE類別中,分別又再劃分了8個子優(yōu)先級實現(xiàn)更細節(jié)的QOS需求,而IDLE只有一個子優(yōu)先級。
另外,我們都知道內核默認對存儲的讀寫都是經過緩存(buffer/cache)的,在這種情況下,cfq是無法區(qū)分當前處理的請求是來自哪一個進程的。
只有在進程使用同步方式(sync read或者sync wirte)或者直接IO(Direct IO)方式進行讀寫的時候,cfq才能區(qū)分出IO請求來自哪個進程。
所以,除了針對每個進程實現(xiàn)的IO隊列以外,還實現(xiàn)了一個公共的隊列用來處理異步請求。
當前內核已經實現(xiàn)了針對IO資源的cgroup資源隔離,所以在以上體系的基礎上,cfq也實現(xiàn)了針對cgroup的調度支持。
總的來說,cfq用了一系列的數據結構實現(xiàn)了以上所有復雜功能的支持,大家可以通過源代碼看到其相關實現(xiàn),文件在源代碼目錄下的block/cfq-iosched.c。
1.1 cfq設計原理
在此,我們對整體數據結構做一個簡要描述:首先,cfq通過一個叫做cfq_data的數據結構維護了整個調度器流程。在一個支持了cgroup功能的cfq中,全部進程被分成了若干個contral group進行管理。
每個cgroup在cfq中都有一個cfq_group的結構進行描述,所有的cgroup都被作為一個調度對象放進一個紅黑樹中,并以vdisktime為key進行排序。
vdisktime這個時間紀錄的是當前cgroup所占用的io時間,每次對cgroup進行調度時,總是通過紅黑樹選擇當前vdisktime時間最少的cgroup進行處理,以保證所有cgroups之間的IO資源占用“公平”。
當然我們知道,cgroup是可以對blkio進行資源比例分配的,其作用原理就是,分配比例大的cgroup占用vdisktime時間增長較慢,分配比例小的vdisktime時間增長較快,快慢與分配比例成正比。
這樣就做到了不同的cgroup分配的IO比例不一樣,并且在cfq的角度看來依然是“公平“的。
選擇好了需要處理的cgroup(cfq_group)之后,調度器需要決策選擇下一步的service_tree。
service_tree這個數據結構對應的都是一系列的紅黑樹,主要目的是用來實現(xiàn)請求優(yōu)先級分類的,就是RT、BE、IDLE的分類。每一個cfq_group都維護了7個service_trees,其定義如下:
其中service_tree_idle就是用來給IDLE類型的請求進行排隊用的紅黑樹。
而上面二維數組,首先之一個維度針對RT和BE分別各實現(xiàn)了一個數組,每一個數組中都維護了三個紅黑樹,分別對應三種不同子類型的請求,分別是:SYNC、SYNC_NOIDLE以及ASYNC。
我們可以認為SYNC相當于SYNC_IDLE并與SYNC_NOIDLE對應。idling是cfq在設計上為了盡量合并連續(xù)的IO請求以達到提高吞吐量的目的而加入的機制,我們可以理解為是一種“空轉”等待機制。
空轉是指,當一個隊列處理一個請求結束后,會在發(fā)生調度之前空等一小會時間,如果下一個請求到來,則可以減少磁頭尋址,繼續(xù)處理順序的IO請求。
為了實現(xiàn)這個功能,cfq在service_tree這層數據結構這實現(xiàn)了SYNC隊列,如果請求是同步順序請求,就入隊這個service tree,如果請求是同步隨機請求,則入隊SYNC_NOIDLE隊列,以判斷下一個請求是否是順序請求。
所有的異步寫操作請求將入隊ASYNC的service tree,并且針對這個隊列沒有空轉等待機制。
此外,cfq還對SSD這樣的硬盤有特殊調整,當cfq發(fā)現(xiàn)存儲設備是一個ssd硬盤這樣的隊列深度更大的設備時,所有針對單獨隊列的空轉都將不生效,所有的IO請求都將入隊SYNC_NOIDLE這個service tree。
每一個service tree都對應了若干個cfq_queue隊列,每個cfq_queue隊列對應一個進程,這個我們后續(xù)再詳細說明。
cfq_group還維護了一個在cgroup內部所有進程公用的異步IO請求隊列,其結構如下:
異步請求也分成了RT、BE、IDLE這三類進行處理,每一類對應一個cfq_queue進行排隊。
BE和RT也實現(xiàn)了優(yōu)先級的支持,每一個類型有IOPRIO_BE_NR這么多個優(yōu)先級,這個值定義為8,數組下標為0-7。
我們目前分析的內核代碼版本為Linux 4.4,可以看出,從cfq的角度來說,已經可以實現(xiàn)異步IO的cgroup支持了,我們需要定義一下這里所謂異步IO的含義,它僅僅表示從內存的buffer/cache中的數據同步到硬盤的IO請求,而不是aio(man 7 aio)或者linux的native異步io以及l(fā)ibaio機制,實際上這些所謂的“異步”IO機制,在內核中都是同步實現(xiàn)的(本質上馮諾伊曼計算機沒有真正的“異步”機制)。
我們在上面已經說明過,由于進程正常情況下都是將數據先寫入buffer/cache,所以這種異步IO都是統(tǒng)一由cfq_group中的async請求隊列處理的。
那么為什么在上面的service_tree中還要實現(xiàn)和一個ASYNC的類型呢?
這當然是為了支持區(qū)分進程的異步IO并使之可以“完全公平”做準備嘍。
實際上在最新的cgroup v2的blkio體系中,內核已經支持了針對buffer IO的cgroup限速支持,而以上這些可能容易混淆的一堆類型,都是在新的體系下需要用到的類型標記。
新體系的復雜度更高了,功能也更加強大,但是大家先不要著急,正式的cgroup v2體系,在Linux 4.5發(fā)布的時候會正式跟大家見面。
我們繼續(xù)選擇service_tree的過程,三種優(yōu)先級類型的service_tree的選擇就是根據類型的優(yōu)先級來做選擇的,RT優(yōu)先級更高,BE其次,IDLE更低。就是說,RT里有,就會一直處理RT,RT沒了再處理BE。
每個service_tree對應一個元素為cfq_queue排隊的紅黑樹,而每個cfq_queue就是內核為進程(線程)創(chuàng)建的請求隊列。
每一個cfq_queue都會維護一個rb_key的變量,這個變量實際上就是這個隊列的IO服務時間(service time)。
這里還是通過紅黑樹找到service time時間最短的那個cfq_queue進行服務,以保證“完全公平”。
選擇好了cfq_queue之后,就要開始處理這個隊列里的IO請求了。這里的調度方式基本跟deadline類似。
cfq_queue會對進入隊列的每一個請求進行兩次入隊,一個放進fifo中,另一個放進按訪問扇區(qū)順序作為key的紅黑樹中。
默認從紅黑樹中取請求進行處理,當請求的延時時間達到deadline時,就從紅黑樹中取等待時間最長的進行處理,以保證請求不被餓死。
這就是整個cfq的調度流程,當然其中還有很多細枝末節(jié)沒有交代,比如合并處理以及順序處理等等。
1.2 cfq的參數調整
理解整個調度流程有助于我們決策如何調整cfq的相關參數。所有cfq的可調參數都可以在/sys/class/block/sda/queue/iosched/目錄下找到,當然,在你的系統(tǒng)上,請將sda替換為相應的磁盤名稱。我們來看一下都有什么:
這些參數部分是跟機械硬盤磁頭尋道方式有關的,如果其說明你看不懂,請先補充相關知識:
back_seek_max:磁頭可以向后尋址的更大范圍,默認值為16M。
back_seek_penalty:向后尋址的懲罰系數。這個值是跟向前尋址進行比較的。
以上兩個是為了防止磁頭尋道發(fā)生抖動而導致尋址過慢而設置的?;舅悸肥沁@樣,一個io請求到來的時候,cfq會根據其尋址位置預估一下其磁頭尋道成本。
設置一個更大值back_seek_max,對于請求所訪問的扇區(qū)號在磁頭后方的請求,只要尋址范圍沒有超過這個值,cfq會像向前尋址的請求一樣處理它。
再設置一個評估成本的系數back_seek_penalty,相對于磁頭向前尋址,向后尋址的距離為1/2(1/back_seek_penalty)時,cfq認為這兩個請求尋址的代價是相同。
這兩個參數實際上是cfq判斷請求合并處理的條件限制,凡事復合這個條件的請求,都會盡量在本次請求處理的時候一起合并處理。
fifo_expire_async:設置異步請求的超時時間。
同步請求和異步請求是區(qū)分不同隊列處理的,cfq在調度的時候一般情況都會優(yōu)先處理同步請求,之后再處理異步請求,除非異步請求符合上述合并處理的條件限制范圍內。
當本進程的隊列被調度時,cfq會優(yōu)先檢查是否有異步請求超時,就是超過fifo_expire_async參數的限制。如果有,則優(yōu)先發(fā)送一個超時的請求,其余請求仍然按照優(yōu)先級以及扇區(qū)編號大小來處理。
fifo_expire_sync:這個參數跟上面的類似,區(qū)別是用來設置同步請求的超時時間。
slice_idle:參數設置了一個等待時間。這讓cfq在切換cfq_queue或service tree的時候等待一段時間,目的是提高機械硬盤的吞吐量。
一般情況下,來自同一個cfq_queue或者service tree的IO請求的尋址局部性更好,所以這樣可以減少磁盤的尋址次數。這個值在機械硬盤上默認為非零。
當然在固態(tài)硬盤或者硬RAID設備上設置這個值為非零會降低存儲的效率,因為固態(tài)硬盤沒有磁頭尋址這個概念,所以在這樣的設備上應該設置為0,關閉此功能。
group_idle:這個參數也跟上一個參數類似,區(qū)別是當cfq要切換cfq_group的時候會等待一段時間。
在cgroup的場景下,如果我們沿用slice_idle的方式,那么空轉等待可能會在cgroup組內每個進程的cfq_queue切換時發(fā)生。
這樣會如果這個進程一直有請求要處理的話,那么直到這個cgroup的配額被耗盡,同組中的其它進程也可能無法被調度到。這樣會導致同組中的其它進程餓死而產生IO性能瓶頸。
在這種情況下,我們可以將slice_idle = 0而group_idle = 8。這樣空轉等待就是以cgroup為單位進行的,而不是以cfq_queue的進程為單位進行,以防止上述問題產生。
low_latency:這個是用來開啟或關閉cfq的低延時(low latency)模式的開關。
當這個開關打開時,cfq將會根據target_latency的參數設置來對每一個進程的分片時間(slice time)進行重新計算。
這將有利于對吞吐量的公平(默認是對時間片分配的公平)。
關閉這個參數(設置為0)將忽略target_latency的值。這將使系統(tǒng)中的進程完全按照時間片方式進行IO資源分配。這個開關默認是打開的。
我們已經知道cfq設計上有“空轉”(idling)這個概念,目的是為了可以讓連續(xù)的讀寫操作盡可能多的合并處理,減少磁頭的尋址操作以便增大吞吐量。
如果有進程總是很快的進行順序讀寫,那么它將因為cfq的空轉等待命中率很高而導致其它需要處理IO的進程響應速度下降,如果另一個需要調度的進程不會發(fā)出大量順序IO行為的話,系統(tǒng)中不同進程IO吞吐量的表現(xiàn)就會很不均衡。
就比如,系統(tǒng)內存的cache中有很多臟頁要寫回時,桌面又要打開一個瀏覽器進行操作,這時臟頁寫回的后臺行為就很可能會大量命中空轉時間,而導致瀏覽器的小量IO一直等待,讓用戶感覺瀏覽器運行響應速度變慢。
這個low_latency主要是對這種情況進行優(yōu)化的選項,當其打開時,系統(tǒng)會根據target_latency的配置對因為命中空轉而大量占用IO吞吐量的進程進行限制,以達到不同進程IO占用的吞吐量的相對均衡。這個開關比較合適在類似桌面應用的場景下打開。
target_latency:當low_latency的值為開啟狀態(tài)時,cfq將根據這個值重新計算每個進程分配的IO時間片長度。
quantum:這個參數用來設置每次從cfq_queue中處理多少個IO請求。在一個隊列處理事件周期中,超過這個數字的IO請求將不會被處理。這個參數只對同步的請求有效。
slice_sync:當一個cfq_queue隊列被調度處理時,它可以被分配的處理總時間是通過這個值來作為一個計算參數指定的。公式為:time_slice = slice_sync + (slice_sync/5 * (4 – prio))。這個參數對同步請求有效。
slice_async:這個值跟上一個類似,區(qū)別是對異步請求有效。
slice_async_rq:這個參數用來限制在一個slice的時間范圍內,一個隊列最多可以處理的異步請求個數。請求被處理的更大個數還跟相關進程被設置的io優(yōu)先級有關。
1.3 cfq的IOPS模式
我們已經知道,默認情況下cfq是以時間片方式支持的帶優(yōu)先級的調度來保證IO資源占用的公平。
高優(yōu)先級的進程將得到更多的時間片長度,而低優(yōu)先級的進程時間片相對較小。
當我們的存儲是一個高速并且支持NCQ(原生指令隊列)的設備的時候,我們更好可以讓其可以從多個cfq隊列中處理多路的請求,以便提升NCQ的利用率。
此時使用時間片的分配方式分配資源就顯得不合時宜了,因為基于時間片的分配,同一時刻最多能處理的請求隊列只有一個。
這時,我們需要切換cfq的模式為IOPS模式。切換方式很簡單,就是將slice_idle=0即可。內核會自動檢測你的存儲設備是否支持NCQ,如果支持的話cfq會自動切換為IOPS模式。
另外,在默認的基于優(yōu)先級的時間片方式下,我們可以使用ionice命令來調整進程的IO優(yōu)先級。進程默認分配的IO優(yōu)先級是根據進程的nice值計算而來的,計算方法可以在man ionice中看到,這里不再廢話。
2、deadline:最終期限調度
deadline調度算法相對cfq要簡單很多。其設計目標是:
在保證請求按照設備扇區(qū)的順序進行訪問的同時,兼顧其它請求不被餓死,要在一個最終期限前被調度到。
我們知道磁頭對磁盤的尋道是可以進行順序訪問和隨機訪問的,因為尋道延時時間的關系,順序訪問時IO的吞吐量更大,隨機訪問的吞吐量小。
如果我們想為一個機械硬盤進行吞吐量優(yōu)化的話,那么就可以讓調度器按照盡量復合順序訪問的IO請求進行排序,之后請求以這樣的順序發(fā)送給硬盤,就可以使IO的吞吐量更大。
但是這樣做也有另一個問題,就是如果此時出現(xiàn)了一個請求,它要訪問的磁道離目前磁頭所在磁道很遠,應用的請求又大量集中在目前磁道附近。
導致大量請求一直會被合并和插隊處理,而那個要訪問比較遠磁道的請求將因為一直不能被調度而餓死。
linux 進程占用了io的介紹就聊到這里吧,感謝你花時間閱讀本站內容,更多關于linux 進程占用了io,解決Linux進程占用IO的問題,linux查看磁盤io的幾種方法,如何提高Linux下塊設備IO的整體性能的信息別忘了在本站進行查找喔。
成都網站推廣找創(chuàng)新互聯(lián),老牌網站營銷公司
成都網站建設公司創(chuàng)新互聯(lián)(www.cdcxhl.com)專注高端網站建設,網頁設計制作,網站維護,網絡營銷,SEO優(yōu)化推廣,快速提升企業(yè)網站排名等一站式服務。IDC基礎服務:云服務器、虛擬主機、網站系統(tǒng)開發(fā)經驗、服務器租用、服務器托管提供四川、成都、綿陽、雅安、重慶、貴州、昆明、鄭州、湖北十堰機房互聯(lián)網數據中心業(yè)務。
本文標題:解決Linux進程占用IO的問題 (linux 進程占用了io)
文章起源:http://m.5511xx.com/article/cdgpghc.html


咨詢
建站咨詢
