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