[深刻理解文件系統之三] Buffer Cache


    因爲訪問內存的速度比訪問磁盤的速度快了幾個數量級,若是能對常常用到的或者最近可能要用到的磁盤上的數據提早讀出來,存放在內存當中,就能明顯縮短讀寫完成的時間,顯著提升性能。爲此在文件系統中緩存機制在許多地方獲得了應用。總結起來,經常使用到的有buffer cache、 page cache、 和DNLC(Directory name look-up cache)三種,分別用在對meta-data、data讀寫以及路徑名解析的場景。 下面重點介紹下buffer cache。node


    爲了能對buffer cache有些基本的感性認識,將從unix和linux系統分別看看buffer cache。linux


Unix系統中buffer的概念,固然須要結合它的數據結構去理解。剛開始本人的理解是有點相似於Linux中的數組

BIO的原型,後來才明白BIO主要是用來記錄從上層傳遞到底層的io請求的 ,而buffer cache是和page
緩存

cache相對的,主要是用來緩存對meta data (blkptr/inde/等) 的訪問的。buffer cache中buffer具體數據結構

的數據結構以下:ide


wKiom1i0Fk3yNTZ-AACFj-zyOMQ095.jpgbuf怎樣組織: 基於b_back/b_ford的雙向鏈表,頭結點是bfreelist。函數

buf如何初始化: 內核啓動的時候初始化,在unix中是初始化NBUF個buffers。性能

Buf cache如何實現:在IO完成、buffer釋放以後,被釋放的buf會被放到av_forw/av_back指向的buf空線程

閒列表裏面去,但此時它的identifier(device ID + block offset)會在被重放被別的請求申請、使用以前unix

一直保留,所以後面的讀只須要直接從內存裏讀出就行了。


基於buf的兩個最主要的接口函數:(對應於buffer cache的主要操做)


bread():

a. call getblk(device ID, block offset); (check whether the buffer is already in buffer caches),

return if true;

b. call iowait() if cache missed

bwrite():和bread()相似,也是調用那連個函數。


而在Linux中buffer cache又是如何實現、怎麼使用的呢?


    Linux中的Buffer cache顧名思義,buffer cache也是緩衝區組成的磁盤高速緩存。

在linux中,每一個緩衝區都存放一個單獨的磁盤塊,塊IO操做依靠buffer cache來減少對磁盤的慢速訪

問,好比讀ext2超級塊、inode節點。


    在linux中buffer cache一樣提供了接口函數,包括:bread()

和unix的區別是bwrite():不存在專門的bwrite(), 這是由於只須要設置磁盤塊對應buffer的dirty位置爲

1, 就能夠被後續的內核線程寫會到磁盤。


Linux如何標識一個buffer to cache: 塊設備ID/major/minor device ID / + 塊內偏移

什麼時候加入cache:在經過bread()讀索引節點或者超級塊的時候

a. getblk() 根據參數中的設備標示符、塊號以及塊大小,在buffer cache 中查找;如命中就返回該buffer; 若是不命中返回一個新的buffer;

b.調用mark_page_accessed()來標記這個新的buffer

c.若是緩衝區已有有效數據,則終止;

d.調用ll_rw_block()開始從磁盤讀數據;

e.經過wait_on_buffer()等待,直到數據傳送完畢。原理是這個函數會把內核current()進程、線程放到那

個新的buffer的緩衝區首部的strucut wait_queue * b_wait 字段隊列中。


如何判斷命中:根據上面的描述,不難看到是在buffer cache 數組中找到了指定id的buffer頭部

什麼時候從cache中調出:(替換策略) LRU  

針對磁盤上的哪些數據:inode/ 超級塊

相關文章
相關標籤/搜索