flashcache mysql_flashcache的实现与分析
最近,由于項目需要,在做關于flashcache的一些工作,主要涉及模塊組織、元數據管理及數據分布、讀寫流程分析、數據在磁盤和 cache(SSD)之間的調度、缺點及可優化方向等一些方面的分析研究。也想,抽空寫一下心得,整理一下最近工作的思路,以彌補自己不善于表達的惡習。 特別是,要深入下去的話,會涉及到整個Linux系統棧的各個層次,從文件系統、磁盤緩存、通用塊層、驅動層,以及DM的工作流程(細節),也遇到了很多 問題,像DM層基于split_bio如何做拆分,在拆分中的邊界問題等,不可能一下子解決,也趁此機會,記錄下心里的困惑。
好了,不啰嗦了,馬上開始!還是從源頭講起。。。
flashcache,是facebook技術團隊開發的新開源項目,主要目的是用SSD硬盤來緩存數據以加速MySQL的一個內核模塊。可以看到,它最初是用來做數據庫加速,但同時,它也被作為通用的緩存模塊而設計,能夠用于任何搭建在塊設備上的應用程序。
工作原理。基于Device Mapper,它將快速的SSD硬盤和普通的硬盤映射成一個 帶緩存的邏輯塊設備,作為用戶操作的接口。用戶直接對這個邏輯設備執行讀寫操作,而不直接對底層的SSD或者普通硬盤操作。如果對底層的這些塊設備操作, 那么會失去作為一個整體提供的緩存功能。
內核層次。flashcache,它是通過在文件系統和塊設備驅動層中間 增加一緩存層次實現的,這里不得不提到DM層的映射機制。由于DM是作為虛擬的塊設備驅動在內核中被注冊的,它不是一個真實的設備驅動,不能完成bio的 處理,因此,它主要是基于映射表對bio進行分解、克隆和重映射,然后,bio到達底層真實的設備驅動,啟動數據傳輸。在Device mapper中,引入了target_driver,每個target_driver由target_type類型描述,代表了一類映射,它們分別用來具 體實現塊設備的映射過程。通過調用某一target_driver的map方法,來映射從上層分發下來的bio,也即是,找到正確的目標設備,并將bio 轉發到目標設備的請求隊列,完成操作。flashcache_target就是這樣一個新的target_driver(作為一個新的映射類 型,target_type是必須的),以模塊化的方式加入到了DM層。
邏輯架構。從源代碼層次分析,可以將flashcache分為這個四個模 塊,調度模塊(也稱‘讀寫模塊’)、邏輯處理模塊(也稱“讀寫后處理模塊”)、底層存儲模塊、以及后臺清理模塊,它們都是基于SSD Layout實現的,構建在SSD布局(后面會分析)之上。其中,調度模塊,在代碼中對應flashcache_map映射函數,它是 flashcache緩存層次數據入口,所以到達邏輯設備的讀寫請求,最終都會經過DM層的處理,通過flashcache_map進入調度模塊。稱之為 “調度”,主要是指,接收到數據后,它會根據bio請求的讀寫類型、是否命中緩存等因素,選擇不同的處理分支,如 flashcache_read/write或者flashcache_uncached_io,在read和write中會選擇是 flashcache_read_hit/miss還是flashcache_write_hit/miss。經過不同分支的讀寫,會調用底層存儲模塊來 完成磁盤或cache的數據讀寫。邏輯處理模塊,在代碼中對應flashcache_io_callback,它在調度模塊通過底層存儲模塊執行數據讀寫 操作完成后回調執行,所以說它是“讀寫后處理模塊”,它是采用狀態機實現的,根據調度模塊中的讀寫類型進行后續的處理,如讀未命中情況下,磁盤讀完成后, 回調到邏輯處理模塊,由它負責將從磁盤讀取的數據寫回到SSD,或者寫未命中情況下,寫SSD完成后,回調到邏輯處理模塊執行元數據的更新,再有就是對調 度模塊中讀寫操作的錯誤進行處理。底層存儲模塊,主要提供了兩種方式來完成真實的數據讀寫,一是由DM提供的dm_io函數,它最終還是通過 submit_bio的方式,將由調度模塊處理過的bio提交到通用塊層,進行轉發到真實的設備驅動,完成數據讀寫;另外,一種方式,kcopyd,是由 內核提供的一種底層拷貝函數,主要負責臟塊的寫回(從SSD到磁盤),會引起元數據的更新。而后臺清理模塊,是針對每個set進行數據清理,它會基于兩種 策略對臟塊做回收:(1)set內臟塊超過了閾值;(2)臟塊超過了設定的空閑時間,即fallow_delay,一般是15分鐘,在15分鐘沒有被操作 則會被優先回收。要注意的是,并沒有單獨的線程在后臺做定期空閑塊回收,必須由IO操作觸發,如果長時間沒有對某set操作,則其中的臟數據很長期保持, 容易危害數據安全。
數據布局(待補充)。
源代碼布局。兩個工作隊列。結合device mapper代碼,特別是dm.c可以知道,在調用flashcache_create工具創建flashcache設備時,會調用 flashcache_ctl函數,執行創建工具,它會創建一工作隊列_delay_clean,主要負責對整個cache設備的臟塊清理,由 flashcache_clean_set在特定條件下調用(見代碼),通過flashcache_clean_all執行對所有sets的掃描與清理。 另外一個工作隊列,_kq_xxx(記不清了),在flashcache_init中,由flashcache模塊加載時執行,通過對5個job鏈表進行 處理,執行元數據的更新與完成處理函數、讀磁盤后的SSD寫入、以及對等待隊列的處理,主要就是負責讀寫后的處理工作隸屬于邏輯處理模塊,即“讀寫后處理 模塊”,由磁盤或SSD讀寫后不同情況下被調度。
調度的時機可以看flashcache_map函數,處理邏輯則主要在函數flashcache_io_callback內部判斷,the same block的等待隊列是否為空,如果不為空,則同樣會調用flashcache_do_handler,執行對等待隊列的處理。
數據調度。對讀,接收到bio,首先,根據 bio->bi_sector,即硬盤的扇區號,得到SSD上的set。其次,在set內查找是否命中,如果命中,則將硬盤的扇區號轉換為SSD的 扇區號,然后將此bio向SSD提交,進行讀取;如果未命中,則首先向硬盤驅動提交bio,從硬盤讀數據,讀取完成后,由回調函數啟動回寫SSD操作,將 bio的扇區號轉換為SSD的=扇區號,然后向SSD驅動程序提交,將硬盤讀取的數據寫入SSD。對寫,同文件系統頁緩沖,并不直接寫入硬盤,而是寫入 SSD,同時,保持一個閥值,一般為20%,在臟塊數目達到此數值時,寫回磁盤。
總結
以上是生活随笔為你收集整理的flashcache mysql_flashcache的实现与分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java程序员闯关题网站_Java程序员
- 下一篇: linux shell 里面执行pyth