如何理解Linux下的磁盤緩存機(jī)制與SSD的寫入放大問題

本篇內(nèi)容介紹了“如何理解Linux下的磁盤緩存機(jī)制與SSD的寫入放大問題”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了酉陽土家族苗族免費(fèi)建站歡迎大家使用!

前段時(shí)間在開發(fā)一個(gè)使用SSD做緩存的系統(tǒng),在高速寫入數(shù)據(jù)時(shí)會(huì)出現(xiàn)大量的磁盤緩存。太多的磁盤緩存如果沒有及時(shí)的寫入磁盤中,在機(jī)器出現(xiàn)問題時(shí)是非常危險(xiǎn)的,這樣會(huì)導(dǎo)致很多的數(shù)據(jù)丟失,但是如果實(shí)時(shí)的將數(shù)據(jù)刷入磁盤中,這樣寫入效率有太低了。為了弄明白Linux系統(tǒng)的這種磁盤寫入特性,最近深入的學(xué)習(xí)了一下。
    VFS(Virtual File System)的存在使得Linux可以兼容不同的文件系統(tǒng),例如ext3、ext4、xfs、ntfs等等,其不僅具有為所有的文件系統(tǒng)實(shí)現(xiàn)一個(gè)通用的外接口的作用,還具有另一個(gè)與系統(tǒng)性能相關(guān)的重要作用——緩存。VFS中引入了高速磁盤緩存的機(jī)制,這屬于一種軟件機(jī)制,允許內(nèi)核將原本存在磁盤上的某些信息保存在RAM中,以便對(duì)這些數(shù)據(jù)的進(jìn)一步訪問能快速進(jìn)行,而不必慢速訪問磁盤本身。高速磁盤緩存可大致分為以下三種:
目錄項(xiàng)高速緩存——主要存放的是描述文件系統(tǒng)路徑名的目錄項(xiàng)對(duì)象
索引節(jié)點(diǎn)高速緩存——主要存放的是描述磁盤索引節(jié)點(diǎn)的索引節(jié)點(diǎn)對(duì)象
頁高速緩存——主要存放的是完整的數(shù)據(jù)頁對(duì)象,每個(gè)頁所包含的數(shù)據(jù)一定屬于某個(gè)文件,同時(shí),所有的文件讀寫操作都依賴于頁高速緩存。其是Linux內(nèi)核所使用的主要磁盤高速緩存。
正是由于緩存的引入,所以VFS文件系統(tǒng)采用了文件數(shù)據(jù)延遲寫的技術(shù),因此,如果在調(diào)用系統(tǒng)接口寫入數(shù)據(jù)時(shí)沒有使用同步寫模式,那么大多數(shù)據(jù)將會(huì)先保存在緩存中,待等到滿足某些條件時(shí)才將數(shù)據(jù)刷入磁盤里。

內(nèi)核是如何將數(shù)據(jù)刷入磁盤的呢?在看完以下兩點(diǎn)后就能得到答案。

1. 把臟頁寫入磁盤
    正如我們所了解的,內(nèi)核不斷用包含塊設(shè)備數(shù)據(jù)的頁填充頁高速緩存。只要進(jìn)程修改了數(shù)據(jù),相應(yīng)的頁就被標(biāo)記為臟頁,即把它的PG_dirty標(biāo)志位置。
    Unix系統(tǒng)允許把臟緩沖區(qū)寫入塊設(shè)備的操作延遲執(zhí)行,因?yàn)檫@種策略可以顯著地提高系統(tǒng)的性能。對(duì)高速緩存中的頁的幾次寫操作可能只需對(duì)相應(yīng)的磁盤塊進(jìn)行一次緩慢的物理更新就可以滿足。此外,寫操作沒有讀操作那么緊迫,因?yàn)檫M(jìn)程通常是不會(huì)因?yàn)檠舆t寫而掛起,而大部分情況都因?yàn)檠舆t讀而掛起。正是由于延遲寫,使得任一物理塊設(shè)備平均為讀請(qǐng)求提供服務(wù)將多于寫請(qǐng)求。
一個(gè)臟頁可能直到最后一刻(即直到系統(tǒng)關(guān)閉時(shí))都一直逗留在主存中。然而,從延遲寫策略的局限性來看,它有兩個(gè)主要的缺點(diǎn):
  一、如果發(fā)生了硬件錯(cuò)誤或者電源掉電的情況,那么就無法再獲得RAM的內(nèi)容,因此,從系統(tǒng)啟動(dòng)以來對(duì)文件進(jìn)行的很多修改就丟失了。
  二、頁高速緩存的大?。ㄓ纱舜娣潘璧腞AM的大?。┚涂梢艽?amp;mdash;—至少要與所訪問塊設(shè)備的大小不同。
因此,在下列條件下把臟頁刷新(寫入)到磁盤:
頁高速緩存變得太滿,但還需要更多的頁,或者臟頁的數(shù)量已經(jīng)太多。
自從頁變成臟頁以來已過去太長(zhǎng)時(shí)間。
進(jìn)程請(qǐng)求對(duì)塊設(shè)備或者特定文件任何待定的變化都進(jìn)行刷新。通過調(diào)用sync()、fsync()或者fdatasync()系統(tǒng)調(diào)用來實(shí)現(xiàn)。
緩沖區(qū)頁的引入是問題更加復(fù)雜。與每個(gè)緩沖區(qū)頁相關(guān)的緩沖區(qū)首部使內(nèi)核能夠了解每個(gè)獨(dú)立塊緩沖區(qū)的狀態(tài)。如果至少有一個(gè)緩沖區(qū)首部的PG_Dirty標(biāo)志被置位,就應(yīng)該設(shè)置相應(yīng)緩沖區(qū)頁的PG_dirty標(biāo)志。當(dāng)內(nèi)核選擇要刷新的緩沖區(qū)時(shí),它掃描相應(yīng)的緩沖區(qū)首部,并只把臟塊的內(nèi)容有效的寫到磁盤。一旦內(nèi)核把緩沖區(qū)的所有臟頁刷新到磁盤,就把頁的PG_dirty標(biāo)志清0。

2. pdflush內(nèi)核線程
    早期版本的Linux使用bdfllush內(nèi)核線程系統(tǒng)地掃描頁高速緩存以搜索要刷新的臟頁,并且使用另一個(gè)內(nèi)核線程kupdate來保證所有的頁不會(huì)“臟”太長(zhǎng)時(shí)間。Linux 2.6用一組通用內(nèi)核線程pdflush替代上述兩個(gè)線程。
這些內(nèi)核線程結(jié)構(gòu)靈活,它們作用于兩個(gè)參數(shù):一個(gè)指向線程要執(zhí)行的函數(shù)的指針和一個(gè)函數(shù)要用的參數(shù)。系統(tǒng)中pdflush內(nèi)核線程的數(shù)量是要?jiǎng)討B(tài)調(diào)整的:pdflush線程太少時(shí)就創(chuàng)建,太多時(shí)就殺死。因?yàn)檫@些內(nèi)核線程所執(zhí)行的函數(shù)可以阻塞,所以創(chuàng)建多個(gè)而不是一個(gè)pdflush內(nèi)核線程可以改善系統(tǒng)性能。
根據(jù)下面的原則控制pdflush線程的產(chǎn)生和消亡:
必須有至少兩個(gè),最多八個(gè)pdflush內(nèi)核線程
如果到最近的1s期間沒有空閑pdflush,就應(yīng)該創(chuàng)建新的pdflush線程
如果最近一次pdflush變?yōu)榭臻e的時(shí)間超過了1s,就應(yīng)該刪除一個(gè)pdflush線程
所有的pdflush內(nèi)核線程都有pdflush_work描述符,其數(shù)據(jù)結(jié)構(gòu)如下:

如何理解Linux下的磁盤緩存機(jī)制與SSD的寫入放大問題

當(dāng)系統(tǒng)沒有要刷新的臟頁時(shí),pdflush線程會(huì)自動(dòng)處于睡眠狀態(tài),最后由pdflush_operation()函數(shù)來喚醒。那么在這個(gè)過程中pdflush內(nèi)核線程主要完成了哪些工作呢?其中一些工作與臟數(shù)據(jù)的刷新有關(guān)。尤其是pdflush通常執(zhí)行下面的回調(diào)函數(shù)之一:
    1. background_writeout(): 系統(tǒng)地掃描頁高速緩存以搜索要刷新的臟頁。
為了得到需要刷新的臟頁,就要徹底的搜索與在磁盤上有映像的索引節(jié)點(diǎn)相應(yīng)的所有address_space對(duì)象(是一棵搜索樹)。由于頁高速緩存可能有大量的頁,如果用一個(gè)單獨(dú)的執(zhí)行流來掃描整個(gè)高速緩存,會(huì)令CPU和磁盤長(zhǎng)時(shí)間繁忙,因此,Linux使用一種復(fù)雜的機(jī)制把對(duì)頁高速緩存的掃描劃分為幾個(gè)執(zhí)行流。當(dāng)內(nèi)存不足或者用戶顯式的(用戶態(tài)進(jìn)程發(fā)出sync()系統(tǒng)調(diào)用等)調(diào)用請(qǐng)求刷新操作時(shí)會(huì)執(zhí)行wakeup_bdflush()函數(shù)。wakeup_bdflush()函數(shù)會(huì)調(diào)用pdflush_operation()喚醒pdflush內(nèi)核線程,并委托它執(zhí)行回調(diào)函數(shù)background_writeout()。background_writeout()函數(shù)有效的從頁高速緩存中獲得指定數(shù)量的臟頁,并把它寫回磁盤。此外,執(zhí)行background_writeout()函數(shù)的pdflush內(nèi)核線程只有在滿足以下兩個(gè)條件下才能被喚醒:一是對(duì)頁高速緩存中的頁內(nèi)容進(jìn)行了修改,二是引起臟頁部分增加到超過某個(gè)臟背景閾值。背景閾值通常設(shè)置為系統(tǒng)中所有頁的10%,不過可以通過修改文件/proc/sys/vm/dirty_background_ratio來調(diào)整該值。
    2. wb_kupdate():檢查頁高速緩存中是否有“臟”了很久時(shí)間的頁,避免當(dāng)一些頁很久沒有被刷新時(shí)發(fā)生饑餓危險(xiǎn)。
 內(nèi)核在初始化期間會(huì)建立wb_timer動(dòng)態(tài)定時(shí)器,其的定時(shí)間距為dirty_writeback_centisecs文件中所規(guī)定的幾百分之一秒(通常是500分之一秒,不過可以通過修改/proc/sys/vm/dirty_writeback_centisecs文件調(diào)整該值)。定時(shí)器函數(shù)會(huì)調(diào)用pdflush_operation()函數(shù),然后將wb_kupdate()函數(shù)的地址傳入。wb_kupdate()函數(shù)遍歷頁高速緩存搜索陳舊的臟索引節(jié)點(diǎn),把已保持臟狀態(tài)時(shí)間超過30秒的頁都寫到磁盤,之后重置定時(shí)器。

PS:關(guān)于SSD的寫入放大問題


    現(xiàn)在固態(tài)硬盤正在越來越多地被作為服務(wù)器磁盤使用。之前在SSD(Solid State Drive)上設(shè)計(jì)并實(shí)現(xiàn)緩存系統(tǒng)用于存儲(chǔ)數(shù)據(jù)塊時(shí)遇到了一些問題,比如在磁盤寫滿后,如果老化掉一些最久未使用的數(shù)據(jù)塊后,繼續(xù)大量寫入新的數(shù)據(jù),隨著時(shí)間的推移,寫入速度變得比剛開始時(shí)慢了許多。為了弄清楚為什么會(huì)出現(xiàn)這樣的情況,于是在網(wǎng)上搜索了一些關(guān)于SSD的資料,原來這種情況是由于SSD硬件設(shè)計(jì)本身決定的,最終映射到應(yīng)用程序上該中現(xiàn)象稱為寫入放大現(xiàn)象(WA: Write amplification),WA是閃存及SSD相關(guān)的一個(gè)極為重要的屬性,這個(gè)術(shù)語在2008年被Intel公司和SiliconSystems公司(于2009 年被西部數(shù)據(jù)收購)第一次提出并在公開稿件里使用。下面簡(jiǎn)單講解一下為什么會(huì)出現(xiàn)這種情況以及是怎樣一個(gè)過程。
    SSD的設(shè)計(jì)完全不同于傳統(tǒng)的機(jī)械磁盤,其是一個(gè)完整的電子設(shè)備,沒有傳統(tǒng)機(jī)械盤的讀寫磁頭。因此,在讀寫數(shù)據(jù)的時(shí)候由于少了磁頭在磁道之間的尋道過程所以SSD能提供較高的IOPS性能。也正因?yàn)槠渖倭舜蓬^的調(diào)度,所以SSD還能減少電量的使用,在數(shù)據(jù)中心中使用對(duì)企業(yè)來說是非常有益的。
    SSD與傳統(tǒng)磁盤相比其有了很大的性能優(yōu)勢(shì),以及較多的優(yōu)點(diǎn),但是事物總是有兩面性的,其也自身也存在一些問題,寫入在SSD中的數(shù)據(jù)是不可以直接更新的,只能通過扇區(qū)覆蓋重寫,在覆蓋重寫之前需要先擦除,而且擦除操作又是不能在扇區(qū)上做的,只能在磁盤的塊上來完成,擦除塊之前需要將原有的還有效的數(shù)據(jù)先讀出,然后在與新來的數(shù)據(jù)一起寫入,這些重復(fù)的操作不單會(huì)增加寫入的數(shù)據(jù)量 ,還會(huì)減少閃存的壽命,更吃光閃存的可用帶寬而間接影響隨機(jī)寫入性能。
如何理解Linux下的磁盤緩存機(jī)制與SSD的寫入放大問題

寫入放大的解決辦法
    在實(shí)際操作中我們很難完全解決掉SSD寫入放大的問題,只能通過某些方法來更有效的減少放大的倍數(shù)。一個(gè)很簡(jiǎn)單的辦法就是將一塊大的SSD硬盤只使用其的一部分容量,比如128GB你只是用64GB,那么最壞的情況就是寫入放大能減少約3倍。當(dāng)然這種方法有點(diǎn)過于浪費(fèi)資源了。另外還可以在寫數(shù)據(jù)時(shí)采用順序?qū)懭耄?dāng)SSD被順序?qū)懭霑r(shí),其寫入放大一般為1,但某些因素會(huì)影響到該值。
    除了上面的方法外,現(xiàn)階段公認(rèn)的比較好的方法是TRIM。TRIM位于操作系統(tǒng)層。操作系統(tǒng)使用TRIM命令來通知SSD某個(gè)page的數(shù)據(jù)不需要了,則可以回收。 支持TRIM的操作系統(tǒng)和以往的主要區(qū)別是刪除一個(gè)Page的操作不同。在磁盤時(shí)期,刪除一個(gè)page之后在文件系統(tǒng)的記錄信息里將該page的標(biāo)志位設(shè)置為可用,但是并沒有將數(shù)據(jù)刪除。使用SSD且支持TRIM的操作系統(tǒng),在刪除一個(gè)page時(shí),會(huì)同時(shí)通知SSD這個(gè)page的數(shù)據(jù)不需要了,SSD內(nèi)部有一個(gè)空閑時(shí)刻的垃圾收集進(jìn)程,在空閑時(shí)刻SSD會(huì)將一些空閑的數(shù)據(jù)集中到一起,然后一起Erase。這樣每次寫操作,就在已經(jīng)Erase好了的Page上寫入新的數(shù)據(jù)。

    雖然其存在寫入放大的問題,但是這并沒有讓我們拒絕使用它。用其來做緩存加速已在很多項(xiàng)目中得到使用,尤其是在數(shù)據(jù)庫緩存項(xiàng)目中,在這些項(xiàng)目中SSD高效的讀性能得到了充分的利用。隨著Facebook的開源項(xiàng)目Flash Cache的發(fā)布,以及Facebook內(nèi)部的大量使用,F(xiàn)lash Cache已經(jīng)成為了一個(gè)比較成熟的技術(shù)方案,這使得更多的公司選擇了SSD來做存儲(chǔ)或者緩存。

“如何理解Linux下的磁盤緩存機(jī)制與SSD的寫入放大問題”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

新聞標(biāo)題:如何理解Linux下的磁盤緩存機(jī)制與SSD的寫入放大問題
瀏覽地址:http://muchs.cn/article22/jpdicc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、虛擬主機(jī)、網(wǎng)站營(yíng)銷微信公眾號(hào)、自適應(yīng)網(wǎng)站微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)