導航:首頁 > 文件教程 > linux文件io

linux文件io

發布時間:2023-03-21 10:31:35

A. linux 文件IO操作中,用read函數讀取文件,有沒有辦法每次只讀取一行,而不是讀取指定的位元組數

sorry,開始來沒注源意空格
char buf[256]; //一行超過256個位元組??
char temp;
int i = 0;
do
{
if(read(fd, &temp, 1) == 0)break;
if(temp == '\n') break;
buf[i++] = temp;
}while(1);
buf[i] =='\0';

B. linux查看磁碟io的幾種方法

linux查看磁碟io的幾種方法

怎樣才能快速的定位到並發高是由於磁碟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 用戶進程空間內改變過優先順序的進程佔用CPU百分比

98.7% id 空閑CPU百分比

0.0% wa 等待輸入輸出的CPU時間百分比

0.0% hi

0.0% si

0.0% wa 的百分比可以大致的體現出當前的磁碟io請求是否頻繁。如果 wa的數量比較大,說明等待輸入輸出的的io比較多。

第二種:用vmstat

vmstat 命令報告關於線程、虛擬內存、磁碟、陷阱和 CPU 活動的統計信息。由 vmstat 命令生成的報告可以用於平衡系統負載活動。系統范圍內的這些統計信息(所有的處理器中)都計算出以百分比表示的平均值,或者計算其總和。

輸入命令:

vmstat 2 5

如果發現等待的進程和處在非中斷睡眠狀態的進程數非常多,並且發送到塊設備的塊數和從塊設備接收到的塊數非常大,那就說明磁碟io比較多。

vmstat參數解釋:

Procs

r: 等待運行的進程數 b: 處在非中斷睡眠狀態的進程數 w: 被交換出去的可運行的進程數。此數由 linux 計算得出,但 linux 並不耗盡交換空間

Memory

swpd: 虛擬內存使用情況,單位:KB

free: 空閑的內存,單位KB

buff: 被用來做為緩存的內存數,單位:KB

Swap

si: 從磁碟交換到內存的交換頁數量,單位:KB/秒

so: 從內存交換到磁碟的交換頁數量,單位:KB/秒

IO

bi: 發送到塊設備的塊數,單位:塊/秒

bo: 從塊設備接收到的塊數,單位:塊/秒

System

in: 每秒的中斷數,包括時鍾中斷

cs: 每秒的環境(上下文)切換次數

CPU

按 CPU 的總使用百分比來顯示

us: CPU 使用時間

sy: CPU 系統使用時間

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 列以每秒千位元組為單位顯示了讀和寫的數據量

如果這兩對數據值都很高的話說明磁碟io操作是很頻繁。

+++++++++++++++++++++++++++++++++++++

linux wa%過高,iostat查看io狀況

1, 安裝  iostat  

yum install sysstat

之後就可以使用 iostat 命令了,

2,入門使用

iostat -d -k 2

參數 -d 表示,顯示設備(磁碟)使用狀態;-k某些使用block為單位的列強制使用Kilobytes為單位;2表示,數據顯示每隔2秒刷新一次。

tps:該設備每秒的傳輸次數(Indicate the number of transfers per second that were issued to the device.)。"一次傳輸"意思是"一次I/O請求"。多個邏輯請求可能會被合並為"一次I/O請求"。"一次傳輸"請求的大小是未知的。kB_read/s:每秒從設備(drive expressed)讀取的數據量;

kB_wrtn/s:每秒向設備(drive expressed)寫入的數據量;

kB_read:讀取的總數據量;kB_wrtn:寫入的總數量數據量;這些單位都為Kilobytes。

指定監控的設備名稱為sda,該命令的輸出結果和上面命令完全相同。

iostat -d sda 2

默認監控所有的硬碟設備,現在指定只監控sda。 

3, -x 參數

iostat還有一個比較常用的選項 -x ,該選項將用於顯示和io相關的擴展數據。

iostat -d -x -k 1 10

輸出信息的含義



4, 常見用法

iostat -d -k 1 10        #查看TPS和吞吐量信息(磁碟讀寫速度單位為KB)

iostat -d -m 2            #查看TPS和吞吐量信息(磁碟讀寫速度單位為MB)

iostat -d -x -k 1 10      #查看設備使用率(%util)、響應時間(await) iostat -c 1 10 #查看cpu狀態

5, 實例分析

iostat -d -k 1 | grep vda

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn

sda10            60.72        18.95        71.53  395637647 1493241908

sda10          299.02      4266.67      129.41      4352        132

sda10          483.84      4589.90      4117.17      4544      4076

sda10          218.00      3360.00      100.00      3360        100

sda10          546.00      8784.00      124.00      8784        124

sda10          827.00    13232.00      136.00      13232        136

上面看到,磁碟每秒傳輸次數平均約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          1.56  28.31  7.84 31.50  43.65    3.16    21.82    1.58    1.19    0.03    0.80  2.61  10.29

sda          1.98  24.75 419.80  6.93 13465.35  253.47  6732.67  126.73    32.15    2.00    4.70  2.00  85.25

sda          3.06  41.84 444.90 54.08 14204.08 2048.98  7102.04  1024.49    32.57    2.10    4.21  1.85  92.24

可以看到磁碟的平均響應時間<5ms,磁碟使用率>80。磁碟響應正常,但是已經很繁忙了。

可以看到磁碟的平均響應時間<5ms,磁碟使用率>90。磁碟響應正常,但是已經很繁忙了。

await:  每一個IO請求的處理的平均時間(單位是微秒毫秒)。這里可以理解為IO的響應時間,一般地系統IO響應時間應該低於5ms,如果大於10ms就比較大了

svctm    表示平均每次設備I/O操作的服務時間(以毫秒為單位)。如果svctm的值與await很接近,表示幾乎沒有I/O等待,磁碟性能很好,

如果await的值遠高於svctm的值,則表示I/O隊列等待太長,  系統上運行的應用程序將變慢。

%util: 在統計時間內所有處理IO時間,除以總共統計時間

所以該參數暗示了設備的繁忙程度

。一般地,如果該參數是100%表示設備已經接近滿負荷運行了(當然如果是多磁碟,即使%util是100%,因為磁碟的並發能力,所以磁碟使用未必就到了瓶頸)。

也可以使用下面的命令,同時顯示cpu和磁碟的使用情況

等待時間超過5ms, 磁碟io有問題

C. 在linux系統中如何查看cpu和io

在 Linux 系統中,可以使用以下命令查看 CPU 信息:

D. Linux系統I/O模型及select、poll、epoll原理和應用

理解Linux的IO模型之前,首先要了解一些基本概念,才能理解這些IO模型設計的依據

操作系統使用虛擬內存來映射物理內存,對於32位的操作系統來說,虛擬地址空間為4G(2^32)。操作系統的核心是內核,為了保護用戶進程不能直接操作內核,保證內核安全,操作系統將虛擬地址空間劃分為內核空間和用戶空間。內核可以訪問全部的地址空間,擁有訪問底層硬體設備的許可權,普通的應用程序需要訪問硬體設備必須通過 系統調用 來實現。

對於Linux系統來說,將虛擬內存的最高1G位元組的空間作為內核空間僅供內核使用,低3G位元組的空間供用戶進程使用,稱為用戶空間。

又被稱為標准I/O,大多數文件系統的默認I/O都是緩存I/O。在Linux系統的緩存I/O機制中,操作系統會將I/O的數據緩存在頁緩存(內存)中,也就是數據先被拷貝到內核的緩沖區(內核地址空間),然後才會從內核緩沖區拷貝到應用程序的緩沖區(用戶地址空間)。

這種方式很明顯的缺點就是數據傳輸過程中需要再應用程序地址空間和內核空間進行多次數據拷貝操作,這些操作帶來的CPU以及內存的開銷是非常大的。

由於Linux系統採用的緩存I/O模式,對於一次I/O訪問,以讀操作舉例,數據先會被拷貝到內核緩沖區,然後才會從內核緩沖區拷貝到應用程序的緩存區,當一個read系統調用發生的時候,會經歷兩個階段:

正是因為這兩個狀態,Linux系統才產生了多種不同的網路I/O模式的方案

Linux系統默認情況下所有socke都是blocking的,一個讀操作流程如下:

以UDP socket為例,當用戶進程調用了recvfrom系統調用,如果數據還沒准備好,應用進程被阻塞,內核直到數據到來且將數據從內核緩沖區拷貝到了應用進程緩沖區,然後向用戶進程返回結果,用戶進程才解除block狀態,重新運行起來。

阻塞模行下只是阻塞了當前的應用進程,其他進程還可以執行,不消耗CPU時間,CPU的利用率較高。

Linux可以設置socket為非阻塞的,非阻塞模式下執行一個讀操作流程如下:

當用戶進程發出recvfrom系統調用時,如果kernel中的數據還沒准備好,recvfrom會立即返回一個error結果,不會阻塞用戶進程,用戶進程收到error時知道數據還沒准備好,過一會再調用recvfrom,直到kernel中的數據准備好了,內核就立即將數據拷貝到用戶內存然後返回ok,這個過程需要用戶進程去輪詢內核數據是否准備好。

非阻塞模型下由於要處理更多的系統調用,因此CPU利用率比較低。

應用進程使用sigaction系統調用,內核立即返回,等到kernel數據准備好時會給用戶進程發送一個信號,告訴用戶進程可以進行IO操作了,然後用戶進程再調用IO系統調用如recvfrom,將數據從內核緩沖區拷貝到應用進程。流程如下:

相比於輪詢的方式,不需要多次系統調用輪詢,信號驅動IO的CPU利用率更高。

非同步IO模型與其他模型最大的區別是,非同步IO在系統調用返回的時候所有操作都已經完成,應用進程既不需要等待數據准備,也不需要在數據到來後等待數據從內核緩沖區拷貝到用戶緩沖區,流程如下:

在數據拷貝完成後,kernel會給用戶進程發送一個信號告訴其read操作完成了。

是用select、poll等待數據,可以等待多個socket中的任一個變為可讀,這一過程會被阻塞,當某個套接字數據到來時返回,之後再用recvfrom系統調用把數據從內核緩存區復制到用戶進程,流程如下:

流程類似阻塞IO,甚至比阻塞IO更差,多使用了一個系統調用,但是IO多路復用最大的特點是讓單個進程能同時處理多個IO事件的能力,又被稱為事件驅動IO,相比於多線程模型,IO復用模型不需要線程的創建、切換、銷毀,系統開銷更小,適合高並發的場景。

select是IO多路復用模型的一種實現,當select函數返回後可以通過輪詢fdset來找到就緒的socket。

優點是幾乎所有平台都支持,缺點在於能夠監聽的fd數量有限,Linux系統上一般為1024,是寫死在宏定義中的,要修改需要重新編譯內核。而且每次都要把所有的fd在用戶空間和內核空間拷貝,這個操作是比較耗時的。

poll和select基本相同,不同的是poll沒有最大fd數量限制(實際也會受到物理資源的限制,因為系統的fd數量是有限的),而且提供了更多的時間類型。

總結:select和poll都需要在返回後通過輪詢的方式檢查就緒的socket,事實上同時連的大量socket在一個時刻只有很少的處於就緒狀態,因此隨著監視的描述符數量的變多,其性能也會逐漸下降。

epoll是select和poll的改進版本,更加靈活,沒有描述符限制。epoll使用一個文件描述符管理多個描述符,將用戶關系的文件描述符的事件存放到內核的一個事件表中,這樣在用戶空間和內核空間的只需一次。

epoll_create()用來創建一個epoll句柄。
epoll_ctl() 用於向內核注冊新的描述符或者是改變某個文件描述符的狀態。已注冊的描述符在內核中會被維護在一棵紅黑樹上,通過回調函數內核會將 I/O 准備好的描述符加入到一個就緒鏈表中管理。
epoll_wait() 可以從就緒鏈表中得到事件完成的描述符,因此進程不需要通過輪詢來獲得事件完成的描述符。

當epoll_wait檢測到描述符IO事件發生並且通知給應用程序時,應用程序可以不立即處理該事件,下次調用epoll_wait還會再次通知該事件,支持block和nonblocking socket。

當epoll_wait檢測到描述符IO事件發生並且通知給應用程序時,應用程序需要立即處理該事件,如果不立即處理,下次調用epoll_wait不會再次通知該事件。

ET模式在很大程度上減少了epoll事件被重復觸發的次數,因此效率要比LT模式高。epoll工作在ET模式的時候,必須使用nonblocking socket,以避免由於一個文件句柄的阻塞讀/阻塞寫操作把處理多個文件描述符的任務餓死。

【segmentfault】 Linux IO模式及 select、poll、epoll詳解
【GitHub】 CyC2018/CS-Notes

E. Linux 磁碟IO

磁碟結構與數據存儲方式, 數據是如何存儲的,又通過怎樣的方式被訪問?

機械硬碟主要由磁碟碟片、磁頭、主軸與傳動軸等組成;數據就存放在磁碟碟片中

現代硬碟尋道都是採用CHS( Cylinder Head Sector )的方式,硬碟讀取數據時,讀寫磁頭沿徑向移動,移到要讀取的扇區所在磁軌的上方,這段時間稱為 尋道時間(seek time) 因讀寫磁頭的起始位置與目標位置之間的距離不同,尋道時間也不同 。磁頭到達指定磁軌後,然後通過碟片的旋轉,使得要讀取的扇區轉到讀寫磁頭的下方,這段時間稱為 旋轉延遲時間(rotational latencytime) 。然後再讀寫數據,讀寫數據也需要時間,這段時間稱為 傳輸時間(transfer time)

固態硬碟主要由主控晶元、快閃記憶體顆粒與緩存組成;數據就存放在快閃記憶體晶元中
通過主控晶元進行定址, 因為是電信號方式, 沒有任何物理結構, 所以定址速度非常快且與數據存儲位置無關

如何查看系統IO狀態

查看磁碟空間

調用 open , fwrite 時到底發生了什麼?

在一個IO過程中,以下5個API/系統調用是必不可少的
Create 函數用來打開一個文件,如果該文件不存在,那麼需要在磁碟上創建該文件
Open 函數用於打開一個指定的文件。如果在 Open 函數中指定 O_CREATE 標記,那麼 Open 函數同樣可以實現 Create 函數的功能
Clos e函數用於釋放文件句柄
Write 和 Read 函數用於實現文件的讀寫過程

O_SYNC (先寫緩存, 但是需要實際落盤之後才返回, 如果接下來有讀請求, 可以從內存讀 ), write-through
O_DSYNC (D=data, 類似O_SYNC, 但是只同步數據, 不同步元數據)
O_DIRECT (直接寫盤, 不經過緩存)
O_ASYNC (非同步IO, 使用信號機制實現, 不推薦, 直接用aio_xxx)
O_NOATIME (讀取的時候不更新文件 atime(access time))

sync() 全局緩存寫回磁碟
fsync() 特定fd的sync()
fdatasync() 只刷數據, 不同步元數據

mount noatime(全局不記錄atime), re方式(只讀), sync(同步方式)

一個IO的傳奇一生 這里有一篇非常好的資料,講述了整個IO過程;
下面簡單記錄下自己的理解的一次常見的Linux IO過程, 想了解更詳細及相關源碼,非常推薦閱讀上面的原文

Linux IO體系結構

[站外圖片上傳中...(image-38a7b-1644137945193)]

Superblock 超級描述了整個文件系統的信息。為了保證可靠性,可以在每個塊組中對superblock進行備份。為了避免superblock冗餘過多,可以採用稀疏存儲的方式,即在若干個塊組中對superblock進行保存,而不需要在所有的塊組中都進行備份
GDT 組描述符表 組描述符表對整個組內的數據布局進行了描述。例如,數據塊點陣圖的起始地址是多少?inode點陣圖的起始地址是多少?inode表的起始地址是多少?塊組中還有多少空閑塊資源等。組描述符表在superblock的後面
數據塊點陣圖 數據塊點陣圖描述了塊組內數據塊的使用情況。如果該數據塊已經被某個文件使用,那麼點陣圖中的對應位會被置1,否則該位為0
Inode點陣圖 Inode點陣圖描述了塊組內inode資源使用情況。如果一個inode資源已經使用,那麼對應位會被置1
Inode表 (即inode資源)和數據塊。這兩塊占據了塊組內的絕大部分空間,特別是數據塊資源

一個文件是由inode進行描述的。一個文件佔用的數據塊block是通過inode管理起來的 。在inode結構中保存了直接塊指針、一級間接塊指針、二級間接塊指針和三級間接塊指針。對於一個小文件,直接可以採用直接塊指針實現對文件塊的訪問;對於一個大文件,需要採用間接塊指針實現對文件塊的訪問

最簡單的調度器。它本質上就是一個鏈表實現的 fifo 隊列,並對請求進行簡單的 合並 處理。
調度器本身並沒有提供任何可以配置的參數

讀寫請求被分成了兩個隊列, 一個用訪問地址作為索引,一個用進入時間作為索引,並且採用兩種方式將這些request管理起來;
在請求處理的過程中,deadline演算法會優先處理那些訪問地址臨近的請求,這樣可以最大程度的減少磁碟抖動的可能性。
只有在有些request即將被餓死的時候,或者沒有辦法進行磁碟順序化操作的時候,deadline才會放棄地址優先策略,轉而處理那些即將被餓死的request

deadline演算法可調整參數
read_expire : 讀請求的超時時間設置(ms)。當一個讀請求入隊deadline的時候,其過期時間將被設置為當前時間+read_expire,並放倒fifo_list中進行排序
write_expire :寫請求的超時時間設置(ms)
fifo_batch :在順序(sort_list)請求進行處理的時候,deadline將以batch為單位進行處理。每一個batch處理的請求個數為這個參數所限制的個數。在一個batch處理的過程中,不會產生是否超時的檢查,也就不會產生額外的磁碟尋道時間。這個參數可以用來平衡順序處理和飢餓時間的矛盾,當飢餓時間需要盡可能的符合預期的時候,我們可以調小這個值,以便盡可能多的檢查是否有飢餓產生並及時處理。增大這個值當然也會增大吞吐量,但是會導致處理飢餓請求的延時變長
writes_starved :這個值是在上述deadline出隊處理第一步時做檢查用的。用來判斷當讀隊列不為空時,寫隊列的飢餓程度是否足夠高,以時deadline放棄讀請求的處理而處理寫請求。當檢查存在有寫請求的時候,deadline並不會立即對寫請求進行處理,而是給相關數據結構中的starved進行累計,如果這是第一次檢查到有寫請求進行處理,那麼這個計數就為1。如果此時writes_starved值為2,則我們認為此時飢餓程度還不足夠高,所以繼續處理讀請求。只有當starved >= writes_starved的時候,deadline才回去處理寫請求。可以認為這個值是用來平衡deadline對讀寫請求處理優先順序狀態的,這個值越大,則寫請求越被滯後處理,越小,寫請求就越可以獲得趨近於讀請求的優先順序
front_merges :當一個新請求進入隊列的時候,如果其請求的扇區距離當前扇區很近,那麼它就是可以被合並處理的。而這個合並可能有兩種情況,一個是向當前位置後合並,另一種是向前合並。在某些場景下,向前合並是不必要的,那麼我們就可以通過這個參數關閉向前合並。默認deadline支持向前合並,設置為0關閉

在調度一個request時,首先需要選擇一個一個合適的cfq_group。Cfq調度器會為每個cfq_group分配一個時間片,當這個時間片耗盡之後,會選擇下一個cfq_group。每個cfq_group都會分配一個vdisktime,並且通過該值採用紅黑樹對cfq_group進行排序。在調度的過程中,每次都會選擇一個vdisktime最小的cfq_group進行處理。
一個cfq_group管理了7棵service tree,每棵service tree管理了需要調度處理的對象cfq_queue。因此,一旦cfq_group被選定之後,需要選擇一棵service tree進行處理。這7棵service tree被分成了三大類,分別為RT、BE和IDLE。這三大類service tree的調度是按照優先順序展開的

通過優先順序可以很容易的選定一類Service tree。當一類service tree被選定之後,採用service time的方式選定一個合適的cfq_queue。每個Service tree是一棵紅黑樹,這些紅黑樹是按照service time進行檢索的,每個cfq_queue都會維護自己的service time。分析到這里,我們知道,cfq演算法通過每個cfq_group的vdisktime值來選定一個cfq_group進行服務,在處理cfq_group的過程通過優先順序選擇一個最需要服務的service tree。通過該Service tree得到最需要服務的cfq_queue。該過程在 cfq_select_queue 函數中實現

一個cfq_queue被選定之後,後面的過程和deadline演算法有點類似。在選擇request的時候需要考慮每個request的延遲等待時間,選擇那種等待時間最長的request進行處理。但是,考慮到磁碟抖動的問題,cfq在處理的時候也會進行順序批量處理,即將那些在磁碟上連續的request批量處理掉

cfq調度演算法的參數
back_seek_max :磁頭可以向後定址的最大范圍,默認值為16M
back_seek_penalty :向後定址的懲罰系數。這個值是跟向前定址進行比較的

fifo_expire_async :設置非同步請求的超時時間。同步請求和非同步請求是區分不同隊列處理的,cfq在調度的時候一般情況都會優先處理同步請求,之後再處理非同步請求,除非非同步請求符合上述合並處理的條件限制范圍內。當本進程的隊列被調度時,cfq會優先檢查是否有非同步請求超時,就是超過fifo_expire_async參數的限制。如果有,則優先發送一個超時的請求,其餘請求仍然按照優先順序以及扇區編號大小來處理
fifo_expire_sync :這個參數跟上面的類似,區別是用來設置同步請求的超時時間
slice_idle :參數設置了一個等待時間。這讓cfq在切換cfq_queue或service tree的時候等待一段時間,目的是提高機械硬碟的吞吐量。一般情況下,來自同一個cfq_queue或者service tree的IO請求的定址局部性更好,所以這樣可以減少磁碟的定址次數。這個值在機械硬碟上默認為非零。當然在固態硬碟或者硬RAID設備上設置這個值為非零會降低存儲的效率,因為固態硬碟沒有磁頭定址這個概念,所以在這樣的設備上應該設置為0,關閉此功能
group_idle :這個參數也跟上一個參數類似,區別是當cfq要切換cfq_group的時候會等待一段時間。在cgroup的場景下,如果我們沿用slice_idle的方式,那麼空轉等待可能會在cgroup組內每個進程的cfq_queue切換時發生。這樣會如果這個進程一直有請求要處理的話,那麼直到這個cgroup的配額被耗盡,同組中的其它進程也可能無法被調度到。這樣會導致同組中的其它進程餓死而產生IO性能瓶頸。在這種情況下,我們可以將slice_idle = 0而group_idle = 8。這樣空轉等待就是以cgroup為單位進行的,而不是以cfq_queue的進程為單位進行,以防止上述問題產生
low_latency :這個是用來開啟或關閉cfq的低延時(low latency)模式的開關。當這個開關打開時,cfq將會根據target_latency的參數設置來對每一個進程的分片時間(slice time)進行重新計算。這將有利於對吞吐量的公平(默認是對時間片分配的公平)。關閉這個參數(設置為0)將忽略target_latency的值。這將使系統中的進程完全按照時間片方式進行IO資源分配。這個開關默認是打開的

target_latency :當low_latency的值為開啟狀態時,cfq將根據這個值重新計算每個進程分配的IO時間片長度
quantum :這個參數用來設置每次從cfq_queue中處理多少個IO請求。在一個隊列處理事件周期中,超過這個數字的IO請求將不會被處理。這個參數只對同步的請求有效
slice_sync :當一個cfq_queue隊列被調度處理時,它可以被分配的處理總時間是通過這個值來作為一個計算參數指定的。公式為: time_slice = slice_sync + (slice_sync/5 * (4 - prio)) 這個參數對同步請求有效
slice_async :這個值跟上一個類似,區別是對非同步請求有效
slice_async_rq :這個參數用來限制在一個slice的時間范圍內,一個隊列最多可以處理的非同步請求個數。請求被處理的最大個數還跟相關進程被設置的io優先順序有關

通常在Linux上使用的IO介面是同步方式的,進程調用 write / read 之後會阻塞陷入到內核態,直到本次IO過程完成之後,才能繼續執行,下面介紹的非同步IO則沒有這種限制,但是當前Linux非同步IO尚未成熟

目前Linux aio還處於較不成熟的階段,只能在 O_DIRECT 方式下才能使用(glibc_aio),也就是無法使用默認的Page Cache機制

正常情況下,使用aio族介面的簡要方式如下:

io_uring 是 2019 年 5 月發布的 Linux 5.1 加入的一個重大特性 —— Linux 下的全新的非同步 I/O 支持,希望能徹底解決長期以來 Linux AIO 的各種不足
io_uring 實現非同步 I/O 的方式其實是一個生產者-消費者模型:

邏輯卷管理
RAID0
RAID1
RAID5(糾錯)
條帶化

Linux系統性能調整:IO過程
Linux的IO調度
一個IO的傳奇一生
理解inode
Linux 文件系統是怎麼工作的?
Linux中Buffer cache性能問題一探究竟
Asynchronous I/O and event notification on linux
AIO 的新歸宿:io_uring
Linux 文件 I/O 進化史(四):io_uring —— 全新的非同步 I/O

F. linux系統如何查看網路IO

首先 、用top命令查看

top - 16:15:05 up 6 days, 6:25, 2 users, load average: 1.45, 1.77, 2.14

Tasks: 147 total, 1 running, 146 sleeping, 0 stopped, 0 zombie

Cpu(s): 0.2% us, 0.2% sy, 0.0% ni, 86.9% id, 12.6% wa, 0.0% hi, 0.0% si

Mem: 4037872k total, 4003648k used, 34224k free, 5512k buffers

Swap: 7164948k total, 629192k used, 6535756k free, 3511184k cached

查看12.6% wa

IO等待所佔用的CPU時間的百分比,高過30%時IO壓力高

其次、 用iostat -x 1 10

avg-cpu: %user %nice %sys %iowait %idle

0.00 0.00 0.25 33.46 66.29

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 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

sdb 0.00 1122 17.00 9.00 192.00 9216.00 96.00 4608.00 123.79 137.23 1033.43 13.17 100.10

sdc 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

查看%util 100.10 %idle 66.29

如果 %util 接近 100%,說明產生的I/O請求太多,I/O系統已經滿負荷,該磁碟可能存在瓶頸。

idle小於70% IO壓力就較大了,一般讀取速度有較多的wait.

同時可以結合vmstat 查看查看b參數(等待資源的進程數)

vmstat -1

如果你想對硬碟做一個IO負荷的壓力測試可以用如下命令

time dd if=/dev/zero bs=1M count=2048 of=direct_2G

此命令為在當前目錄下新建一個2G的文件

我們在新建文件夾的同時來測試IO的負荷情況。

G. linux查看網路io使用率

sar -n DEV

不帶其他參數 看當天的網路IO 預設取樣時間為1秒,間隔為10分鍾
加 -f /var/log/sa/saxx可察看某日的歷史,xx為當月或上月的日期(day of the month)前提是改文件存在

察看即時IO用sar -n DEV 1 999 表示取樣間隔為1秒,取樣999次

具體欄位的含義我就不醉贅述了

H. 如何提高Linux伺服器磁碟io性能

您好,很高興為您解答。

在現有文件系統下進行優化:
linux內核和各個文件系統採用了幾個優化方案來提升磁碟訪問速度。但這些優化方案需要在我們的伺服器設計中進行配合才能得到充分發揮。
文件系統緩存
linux內核會將大部分空閑內存交給虛擬文件系統,來作為文件緩存,叫做page cache。在內存不足時,這部分內存會採用lru演算法進行淘汰。通過free命令查看內存,顯示為cached的部分就是文件緩存了。

如何針對性優化:
lru並不是一個優秀淘汰演算法,lru最大的優勢是普適性好,在各種使用場景下都能起到一定的效果。如果能找到當前使用場景下,文件被訪問的統計特徵,針 對性的寫一個淘汰演算法,可以大幅提升文件緩存的命中率。對於http正向代理來說,一個好的淘汰演算法可以用1GB內存達到lru演算法100GB內存的緩存 效果。如果不打算寫一個新的淘汰演算法,一般不需要在應用層再搭一個文件cache程序來做緩存。

最小分配:
當文件擴大,需要分配磁碟空間時,大部分文件系統不會僅僅只分配當前需要的磁碟空間,而是會多分配一些磁碟空間。這樣下次文件擴大時就可以使用已經分配好的空間,而不會頻繁的去分配新空間。
例如ext3下,每次分配磁碟空間時,最小是分配8KB。
最小分配的副作用是會浪費一些磁碟空間(分配了但是又沒有使用)

如何針對性優化:
我們在reiserfs下將最小分配空間從8KB改大到128K後提升了30%的磁碟io性能。如果當前使用場景下小文件很多,把預分配改大就會浪費很多 磁碟空間,所以這個數值要根據當前使用場景來設定。似乎要直接改源代碼才能生效,不太記得了,09年的時候改的,有興趣的同學自己google吧。

io訪問調度:
在同時有多個io訪問時,linux內核可以對這些io訪問按LBA進行合並和排序,這樣磁頭在移動時,可以「順便」讀出移動過程中的數據。
SATA等磁碟甚至在磁碟中內置了io排序來進一步提升性能,一般需要在主板中進行配置才能啟動磁碟內置io排序。linux的io排序是根據LBA進行的,但LBA是一個一維線性地址,無法完全反應出二維的圓形磁碟,所以磁碟的內置io排序能達到更好的效果。

如何針對性優化:
io訪問調度能大幅提升io性能,前提是應用層同時發起了足夠的io訪問供linux去調度。
怎樣才能從應用層同時向內核發起多個io訪問呢?
方案一是用aio_read非同步發起多個文件讀寫請求。
方案二是使用磁碟線程池同時發起多個文件讀寫請求。
對我們的http正向代理來說,採用16個線程讀寫磁碟可以將性能提升到2.5倍左右。具體開多少個線程/進程,可以根據具體使用場景來決定。

小提示:
將文件句柄設置為非阻塞時,進程還是會睡眠等待磁碟io,非阻塞對於文件讀寫是不生效的。在正常情況下,讀文件只會引入十幾毫秒睡眠,所以不太明顯;而在磁碟io極大時,讀文件會引起十秒以上的進程睡眠。

預讀取:
linux內核可以預測我們「將來的讀請求」並提前將數據讀取出來。通過預讀取可以減少讀io的次數,並且減小讀請求的延時。

如何針對性優化:
預讀取的預測准確率是有限的,與其依賴預讀取,不如我們直接開一個較大的緩沖區,一次性將文件讀出來再慢慢處理;盡量不要開一個較小的緩沖區,循環讀文件/處理文件。
雖然說「預讀取」和「延遲分配」能起到類似的作用,但是我們自己擴大讀寫緩沖區效果要更好。

延遲分配:
當文件擴大,需要分配磁碟空間時,可以不立即進行分配,而是暫存在內存中,將多次分配磁碟空間的請求聚合在一起後,再進行一次性分配。
延遲分配的目的也是減少分配次數,從而減少文件不連續。

延遲分配的副作用有幾個:
1、如果應用程序每次寫數據後都通過fsync等介面進行強制刷新,延遲分配將不起作用
2、延遲分配有可能間歇性引入一個較大的磁碟IO延時(因為要一次性向磁碟寫入較多數據)
只有少數新文件系統支持這個特性

如何針對性優化:
如果不是對安全性(是否允許丟失)要求極高的數據,可以直接在應用程序里緩存起來,積累到一定大小再寫入,效果比文件系統的延遲分配更好。如果對安全性要求極高,建議經常用fsync強制刷新。

在線磁碟碎片整理:
Ext4提供了一款碎片整理工具,叫e4defrag,主要包含三個功能:
1、讓每個文件連續存儲
2、盡量讓每個目錄下的文件連續存儲
3、通過整理空閑磁碟空間,讓接下來的分配更不容易產生碎片

如何針對性優化:
「讓每個目錄下的文件連續存儲」是一個極有價值的功能。
傳統的做法是通過拼接圖片來將這10張圖片合並到一張大圖中,再由前端將大圖切成10張小圖。
有了e4defrag後,可以將需連續訪問的文件放在同一個文件夾下,再定期使用e4defrag進行磁碟整理。

實現自己的文件系統:
在大部分伺服器上,不需要支持「修改文件」這個功能。一旦文件創建好,就不能再做修改操作,只支持讀取和刪除。在這個前提下,我們可以消滅所有文件碎片,把磁碟io效率提升到理論極限。

有一個公式可以衡量磁碟io的效率:
磁碟利用率 = 傳輸時間/(平均尋道時間+傳輸時間)

如若滿意,請點擊回答右側【採納答案】,如若還有問題,請點擊【追問】

~ O(∩_∩)O~

I. Linux磁碟IO流程

文件IO的分層設計

先看圖:

malloc的buf對應application buffer,用戶空間;

fwrite是系統提供的最上層介面,也是最常用的接纖嘩口。它在用戶進程空間開辟一個CLib buffer,將多次小數據量相鄰寫操作(application buffer)先緩存起來,合並,最終調用write函數一次性寫入(或者將大塊數據分解多次write調用);

write函數通過調用系統調用介面,將數據從應用層到內核慎巧層,所以write會觸發內核態/用戶態切換。當數據到達page cache後,內核並不會立即把數據往下傳遞。而是返回用戶空間。數據什麼時候寫入硬碟,有內核IO調度決定,所以write是一個非同步調用;

read調用是先檢查page cache裡面是否有數據,如果有,就取出來返回用戶,如果沒有,就同步傳遞寬豎鍵下去並等待有數據,再返回用戶,所以read是一個同步過程;

fclose隱含fflush函數,fflush只負責把數據從Clibbuffer拷貝到pagecache中返回,並沒有刷新到磁碟上,刷新到磁碟上可以使用fsync函數;

即便fsync仍有可能沒寫到磁碟上,一是磁碟有緩存,二是即便關閉緩存也可能為了跑分沒有真正關閉;

** 一致性
fwrite使用用戶進程私有空間,多線程必然需要做同步。write如果寫大小小於PIPE_BUF,是原子操作。根據已知信息,內核所做僅限於此,如果兩個進程同時寫文件,可能出現錯亂,需要實測。

** 安全性
從前面的分層設計來看,使用fsync函數可以最大限度保障安全寫入,但仍然沒有絕對的安全性。

另外一張圖

閱讀全文

與linux文件io相關的資料

熱點內容
maya粒子表達式教程 瀏覽:84
抖音小視頻如何掛app 瀏覽:283
cad怎麼設置替補文件 瀏覽:790
win10啟動文件是空的 瀏覽:397
jk網站有哪些 瀏覽:134
學編程和3d哪個更好 瀏覽:932
win10移動硬碟文件無法打開 瀏覽:385
文件名是亂碼還刪不掉 瀏覽:643
蘋果鍵盤怎麼打開任務管理器 瀏覽:437
手機桌面文件名字大全 瀏覽:334
tplink默認無線密碼是多少 瀏覽:33
ipaddgm文件 瀏覽:99
lua語言編程用哪個平台 瀏覽:272
政采雲如何導出pdf投標文件 瀏覽:529
php獲取postjson數據 瀏覽:551
javatimetask 瀏覽:16
編程的話要什麼證件 瀏覽:94
錢脈通微信多開 瀏覽:878
中學生學編程哪個培訓機構好 瀏覽:852
榮耀路由TV設置文件共享錯誤 瀏覽:525

友情鏈接