FlashCache初探(二)


Flashcache : A Write Back Block Cache for Linux
  Author: Mohan Srinivasan
-----------------------------------------------
 
Introduction :
============
Flashcache is a write back block cache Linux kernel module. This
document describes the design, futures ideas, configuration, tuning of
the flashcache and concludes with a note covering the testability
hooks within flashcache and the testing that we did. Flashcache was
built primarily as a block cache for InnoDB but is general purpose and
can be used by other applications as well.

Flashcache設計

flashcache使用了Linux Device Mapper(DM),是Linux 存儲棧架構中的一部分,在創建SW-raid和其他組件的時候經常會涉及到,例如,LVM使用的就是DM。

緩存的結構使用了一致性哈希,緩存被划分成多個固定大小的集合(buckets),桶內使用線性地查找block。一致性哈希使用的好處很多(后面的部分將會介紹)並且能夠很好的發揮使用。

block size,set size和cache size都是可以配置的參數,在cache創建需要。默認的設置:block size 512,幾乎沒有什么理由需要修改這個值。(思:意思是推薦使用512)

在以下的內容中,dbn意思是"disk block number",邏輯設備的塊號。

計算一個指定的集合屬於哪個dbn的方式

target set=(dbn/block size/set size)mod(number of sets)

確認了集合后,在集合內部線性查找block。一個范圍的disk block映射在一個指定的集合內。

DM layer在IO發送到cache layer之前將所有的IO操作轉化為對block的操作(思:即對其轉換等操作)。默認地,flashcache緩存所有的blosksize IO,但是可以配置為之緩存隨機IO忽略順序IO。

Cache  set放置策略是FIFO或者LRU。默認是FIFO但是策略可以在運行期間任何一個點進行切換同時sysctl(see the configuration and tuning section)。

處理緩存的讀操作,計算目標集合(根據dbn)現行查找到block。當緩存命中事,就從flash中獎數據讀取出來;若未命中,數據則從磁盤中讀取數據,將數據寫入到flash中,然后返回數據。

由於flashcache采用的寫回策略,寫操作僅僅寫入到flash中,同步更新cache的metadata(標記cache block是臟塊),則完成寫操作,當block再次被寫入事,metadata就不用再更新了。(因為已經標記為臟塊了)。

必須注意的是,in the first cut,cache寫入不是原子的,例如會有"Torn Page Problem"存在。一旦遇上斷電或者寫錯誤,那么有可能部分塊以紀念館寫入成功。我們已經有了idea去fix這個問題,並提供原子的cache寫入操作(看the Futures section)。

對於每一個緩存塊都有一個on-flash metadata為了cache的持久化(是這個意思么?

Each cache block has on-flash metadata associated with it for cache
persistence.),每個block的metadata又dbn(disk block cached in this slot)and flags(Dirty,VALID,INVALID).
cache metadata只有在寫操作或者一個cache block被清除的時候需要更新。執行寫操作時,將flag標記為dirty;被清除時標記為~dirty。為了最小化flash寫操作,cache block metadata在讀的時候不需要更新。
另外,我們還有一個0n-flash cache superblock,包含cache的參數(在cache重啟時讀取),也包含cache關閉是否是clean的(順序關閉或者節點宕機,斷電等等)。
當cache是clean shutdown時,所有cache blocks的metadat都會被寫入到flash中。在關機以后,VALID和DIRTY的塊在cache重啟時將會被持久化(??)。當節點宕機或者斷電時,只有dirty cache blocks在cache重新啟動時持久化(???)。節點宕機或者斷電不會導致數據丟失,但是有可能導致cache丟失valid和non-dirty的cached blocks(為什么?)。
cache 的metadata在可能的時候再批量進行更新。所以如果我們有多個待更新的metadata位於同一個metadata的sector中,可以集中一次更新,當一個文件順序寫入是,我們通常將多個metadata一起更新。
臟的緩存塊會在后台寫入到disk中。flashcache的延遲寫入是由可配置的參數dirty threshold控制的。Flashcache維持每個set中的dirty block的百分比在dirty threshold之下,當set中臟塊百分比超過了臟塊閾值之后,set將被清理(即寫入到disk中並把metadata清空)。
DIRTY blocks的清理選擇基於放置策略(FIFO Vs LRU)。當我們選擇一個目標set清理時,對這些block進行排序,將塊進行合並成大的IO,寫入到disk中。
 
之前提到過,在IO操作發送到flashcache之前,DM將IO分裂為blocksize的塊操作。對於小IO或者一個IO操作跨兩個cache blocks,直接將IO發送到disk中。但是在這之前,我們將cacheblocks中對應這些io的都標記為invalidate。如果覆蓋的cacheblock為DIRTY,將數據寫入到cacheblock中,並clean。將IO所在的cacheblocks置為invalidate非常容易,使用一致性哈希算法計算io所在set。
Flashcache支持塊校驗,在cache上計算,並且在每次cache讀取時有效。塊校驗是可以編譯選擇的,由於“Torn page”的問題,默認是關閉的。如果cache寫失敗,有的block已經成功提交到flash中,那么block checksum出現錯誤的block以及之后的所有的block寫入都認為是失敗的。
 
那么metadata的開銷有多大呢?每個cache block在內存中有24字節的狀態(64位架構)和在flash上有16字節的狀態。對於一個300GB的cache有16KB的blocks,有將近20 Million cacheblocks,內存元數據消耗是480MB,如果我們配置300GB的cache使用4KB的page是,內存消耗為1.8GB。
 
如果一個進程標記他為不是用緩存,當進程退出時flashcache沒有辦法執行clean操作,(因為Linuxkernel沒有at_exit()鈎子)。應用程序必須解決這個問題(見下文配置)。關於清理問題的解決方法是,使用緩存控制flashcache偽文件系統,在一個進程退出時最后一個關閉的fd負責清理工作。
In spite of the limitations, we think the ability to mark Direct IOs
issued by a pid will be valuable to prevent backups from wiping out
the cache.
盡管存在這些局限性,我們認為一個pid標記的直接IO能夠有效的組織從cache中的擦除。
 
另外,除非特別標注pids不使用緩存,否則用戶使用系統調用"skip_seq_thresh_kb"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM