寫在前面
在開始正式的討論前,我先拋出幾個問題:
談到磁盤時,常說的HDD磁盤和SSD磁盤最大的區(qū)別是什么?這些差異會影響我們的系統(tǒng)設(shè)計嗎?
單線程寫文件有點(diǎn)慢,那多開幾個線程一起寫是不是可以加速呢?
write(2)函數(shù)成功返回了,數(shù)據(jù)就已經(jīng)成功寫入磁盤了嗎?此時設(shè)備斷電會有影響嗎?會丟失數(shù)據(jù)嗎?
write(2)調(diào)用是原子的嗎?多線程寫文件是否要對文件加鎖?有沒有例外,比如O_APPEND方式?
坊間傳聞,mmap(2)的方式讀文件比傳統(tǒng)的方式要快,因為少一次拷貝。真是這樣嗎?為什么少一次拷貝?
如果你覺得這些問題都很簡單,都能很明確的回答上來。那么很遺憾這篇文章不是為你準(zhǔn)備的,你可以關(guān)掉網(wǎng)頁去做其他更有意義的事情了。如果你覺得無法明確的回答這些問題,那么就耐心地讀完這篇文章,相信不會浪費(fèi)你的時間。受限于個人時間和文章篇幅,部分議題如果我不能給出更好的解釋或者已有專業(yè)和嚴(yán)謹(jǐn)?shù)?a href="http://srfitnesspt.com/soft/special/" target="_blank">資料,就只會給出相關(guān)的參考文獻(xiàn)的鏈接,請讀者自行參閱。
言歸正傳,我們的討論從存儲器的層次結(jié)構(gòu)開始。
存儲器的金字塔結(jié)構(gòu)
受限于存儲介質(zhì)的存取速率和成本,現(xiàn)代計算機(jī)的存儲結(jié)構(gòu)呈現(xiàn)為金字塔型[1]。越往塔頂,存取效率越高、但成本也越高,所以容量也就越小。得益于程序訪問的局部性原理[2],這種節(jié)省成本的做法也能取得不俗的運(yùn)行效率。從存儲器的層次結(jié)構(gòu)以及計算機(jī)對數(shù)據(jù)的處理方式來看,上層一般作為下層的Cache層來使用(廣義上的Cache)。比如寄存器緩存CPU Cache的數(shù)據(jù),CPU Cache L1~L3層視具體實(shí)現(xiàn)彼此緩存或直接緩存內(nèi)存的數(shù)據(jù),而內(nèi)存往往緩存來自本地磁盤的數(shù)據(jù)。
本文主要討論磁盤IO操作,故只聚焦于Local Disk的訪問特性和其與DRAM之間的數(shù)據(jù)交互。
無處不在的緩存
如圖,當(dāng)程序調(diào)用各類文件操作函數(shù)后,用戶數(shù)據(jù)(User Data)到達(dá)磁盤(Disk)的流程如圖所示[3]。圖中描述了Linux下文件操作函數(shù)的層級關(guān)系和內(nèi)存緩存層的存在位置。中間的黑色實(shí)線是用戶態(tài)和內(nèi)核態(tài)的分界線。
從上往下分析這張圖,首先是C語言stdio庫定義的相關(guān)文件操作函數(shù),這些都是用戶態(tài)實(shí)現(xiàn)的跨平臺封裝函數(shù)。stdio中實(shí)現(xiàn)的文件操作函數(shù)有自己的stdio buffer,這是在用戶態(tài)實(shí)現(xiàn)的緩存。此處使用緩存的原因很簡單——系統(tǒng)調(diào)用總是昂貴的。如果用戶代碼以較小的size不斷的讀或?qū)懳募脑挘瑂tdio庫將多次的讀或者寫操作通過buffer進(jìn)行聚合是可以提高程序運(yùn)行效率的。stdio庫同時也支持fflush(3)函數(shù)來主動的刷新buffer,主動的調(diào)用底層的系統(tǒng)調(diào)用立即更新buffer里的數(shù)據(jù)。特別地,setbuf(3)函數(shù)可以對stdio庫的用戶態(tài)buffer進(jìn)行設(shè)置,甚至取消buffer的使用。
系統(tǒng)調(diào)用的read(2)/write(2)和真實(shí)的磁盤讀寫之間也存在一層buffer,這里用術(shù)語Kernel buffer cache來指代這一層緩存。在Linux下,文件的緩存習(xí)慣性的稱之為Page Cache,而更低一級的設(shè)備的緩存稱之為Buffer Cache. 這兩個概念很容易混淆,這里簡單的介紹下概念上的區(qū)別:Page Cache用于緩存文件的內(nèi)容,和文件系統(tǒng)比較相關(guān)。文件的內(nèi)容需要映射到實(shí)際的物理磁盤,這種映射關(guān)系由文件系統(tǒng)來完成;Buffer Cache用于緩存存儲設(shè)備塊(比如磁盤扇區(qū))的數(shù)據(jù),而不關(guān)心是否有文件系統(tǒng)的存在(文件系統(tǒng)的元數(shù)據(jù)緩存在Buffer Cache中)。
綜上,既然討論Linux下的IO操作,自然是跳過stdio庫的用戶態(tài)這一堆東西,直接討論系統(tǒng)調(diào)用層面的概念了。對stdio庫的IO層有興趣的同學(xué)可以自行去了解。從上文的描述中也介紹了文件的內(nèi)核級緩存是保存在文件系統(tǒng)的Page Cache中的。所以下篇的討論基本上是討論IO相關(guān)的系統(tǒng)調(diào)用和文件系統(tǒng)Page Cache的一些機(jī)制。
-
存儲器
+關(guān)注
關(guān)注
38文章
7408瀏覽量
163425 -
Linux
+關(guān)注
關(guān)注
87文章
11182瀏覽量
208514
原文標(biāo)題:淺墨: 聊聊Linux IO(上)
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論