一、數據寫入磁盤流程
當執行向磁盤寫入數據操作的時候,會發生如下的一系列基本操作。假設文件數據存在于磁盤扇區上,并且已經被讀入到頁緩存中。
- 進程使用write()系統調用寫入文件。
- 內核更新映射到文件的page cache。
- 內核線程pdflush負責把頁緩存刷入到磁盤中。
- 文件系統層把各個塊緩存放入一個bio結構,并且提交一個寫入到塊設備層的請求。
- 塊設備層從上層獲得請求,執行I/O elevator操作,把請求放入到I/O請求隊列中。
- 磁盤驅動,例如SCSI或其它特定驅動將會負責寫操作。
- 磁盤驅動固件執行硬件操作,例如尋址、旋轉、數據傳送到磁盤的扇區
二、物理磁盤結構
磁盤是計算機主要的存儲設備,也是計算機的主要構成硬件,磁盤主要由盤片、磁頭、磁道、扇區、柱面這幾部分組成。
- 盤片 : 磁盤由多個盤片組成,數據存儲在這些盤片上,通過盤片的轉動來讓磁頭讀取數據的。
- 磁頭: 在需要讀取數據的時候,磁頭就會移到這個盤片上面讀取數據,磁頭和盤片之間的距離非常小,但不會接觸到盤片。如果出現斷電的情況,那么磁頭就會從盤片上移開移回到原來的位置。
- 磁道: 每個盤片就像一個“目標靶盤”,從中心向外分布著一圈圈的圓環,這些圓環被稱為磁道。磁道是數據存儲的基本單位,每個磁道上可以存儲大量的數據。
- 扇區: 磁道是由一個一個的小圓環組成,每一個圓圈又進行了一個更小的劃分,被稱為扇區,如下面所示,一個磁道由八個扇區組成,每個扇區存儲512個字節數據。
- 柱面: 柱面是多個盤片的磁道在相同位置的集合,如下面的黃色部分,四個盤面都有這個黃色的磁道,這樣黃色部分的四個磁道就形成了一個圓柱體狀的柱面。
三、緩存與臟數據
現代處理器的訪問速度已經遠遠超過了主存儲器的訪問速度,為了解決這個問題,在CPU和內存之間添加一個高速內存, 這個高速內存容量小,只用來存儲CPU執行時常用的指令。既保證了硬件成本,又提高了CPU的訪問速度。
高緩存命中率是提升性能的關鍵。 為了獲得高緩存命中率, 使用”局部性引用“的技術。 這個技術基于如下的原則:
最近使用過的數據即將被使用的可能性很高(時間局部性, temporal locality)。
使用過數據的附近數據被使用的可能性很高(空間局部性, spatial locality)
Linux在很多組件中用到了這個原則,例如頁緩存、文件對象緩存(i-node緩存、目錄條 目緩存等等)、預讀緩沖區等。如下圖所示:
在進程從磁盤中讀數據時,數據被復制到內存中。該進程和其它進程都可以在內存緩存中讀 取同樣的數據副本。當進程嘗試改變數據,進程首先修改內存中的數據,這時候,磁盤和內 存中的數據就不一致了,內存中的數據就叫做臟緩沖(dirty buffer)。臟緩沖應該盡快同步到 磁盤上,否則,如果突然崩潰,內存中的數據會丟失。
同步臟緩沖的進程叫做flush,在Linux內核2.6中,pdflush內核線程負責把數據寫入到磁盤 上。數據會定時刷新(kupdate),或者當內存中的臟緩沖到了閥值的比例的時候 (bdflush)。這個閥值在/proc/sys/vm/dirty_background_ratio
文件中。
參考:
I/O子系統與磁盤調度詳解-CSDN博客
https://juejin.cn/post/6844903747189997581
https://zhuanlan.zhihu.com/p/25779982455