基于SSD固態(tài)硬盤的數(shù)據(jù)庫性能優(yōu)化
NOR和NAND
NOR和NAND都是閃存技術(shù)的一種,NOR是Intel公司開發(fā)的,它有點(diǎn)類似于內(nèi)存,允許通過地址直接訪問任何一個內(nèi)存單元,缺點(diǎn)是:密度低(容量小),寫入和擦除的速度很慢。NAND是東芝公司開發(fā)的,它密度高(容量大),寫入和擦除的速度都很快,但是必須通過特定的IO接口經(jīng)過地址轉(zhuǎn)換之后才可以訪問,有些類似于磁盤。
我們現(xiàn)在廣泛使用的U盤,SD卡,SSD都屬于NAND類型,廠商將flash memory封裝成為不同的接口,比如Intel的SSD就是采用了SATA的接口,訪問與普通SATA磁盤一樣,還有一些企業(yè)級的閃存卡,比如FusionIO,則封裝為PCIe接口。
SLC和MLC
SLC是單極單元,MLC是多級單元,兩者的差異在于每單元存儲的數(shù)據(jù)量(密度),SLC每單元只存儲一位,只包含0和1兩個電壓符,MLC每單元可以存儲兩位,包含四個電壓符(00,01,10,11)。顯然,MLC的存儲容量比SLC大,但是SLC更簡單可靠,SLC讀取和寫入的速度都比MLC更快,而且SLC比MLC更耐用,MLC每單元可擦除1w次,而SLC可擦除10w次,所以,企業(yè)級的閃存產(chǎn)品一般都選用SLC,這也是為什么企業(yè)級產(chǎn)品比家用產(chǎn)品貴很多的原因。
SSD的技術(shù)特點(diǎn)
SSD與傳統(tǒng)磁盤相比,***是沒有機(jī)械裝置,第二是由磁介質(zhì)改為了電介質(zhì)。在SSD內(nèi)部有一個FTL(Flash Transalation Layer),它相當(dāng)于磁盤中的控制器,主要功能就是作地址映射,將flash memory的物理地址映射為磁盤的LBA邏輯地址,并提供給OS作透明訪問。
SSD沒有傳統(tǒng)磁盤的尋道時間和延遲時間,所以SSD可以提供非常高的隨機(jī)讀取能力,這是它的***優(yōu)勢,SLC類型的SSD通常可以提供超過35000的IOPS,傳統(tǒng)15k的SAS磁盤,最多也只能達(dá)到160個IOPS,這對于傳統(tǒng)磁盤來說幾乎就是個天文數(shù)字。SSD連續(xù)讀的能力相比普通磁盤優(yōu)勢并不明顯,因為連續(xù)讀對于傳統(tǒng)磁盤來說,并不需要尋道時間,15k的SAS磁盤,連續(xù)讀的吞吐能力可以達(dá)到130MB,而SLC類型的SSD可以達(dá)到170-200MB,我們看到在吞吐量方面,SSD雖然比傳統(tǒng)磁盤高一些,但優(yōu)勢雖然并不明顯。
SSD的寫操作比較特殊,SSD的最小寫入單元為4KB,稱為頁(page),當(dāng)寫入空白位置時可以按照4KB的單位寫入,但是如果需要改寫某個單元時,則需要一個額外的擦除(erase)動作,擦除的單位一般是128個page(512KB),每個擦除單元稱為塊(block)。如果向一個空白的page寫入信息時,可以直接寫入而無需擦除,但是如果需要改寫某個存儲單元(page)的數(shù)據(jù),必須首先將整個block讀入緩存,然后修改數(shù)據(jù),并擦除整個block的數(shù)據(jù),***將整個block寫入,很顯然,SSD改寫數(shù)據(jù)的代價很高,SSD的這個特性,我們稱之為erase-before-write。
經(jīng)過測試,SLC SSD的隨即寫性能可以達(dá)到3000個左右的IOPS,連續(xù)寫的吞吐量可以達(dá)到170MB,這個數(shù)據(jù)還是比傳統(tǒng)磁盤高出不少。但是,隨著SSD的不斷寫入,當(dāng)越來越多的數(shù)據(jù)需要被改寫時,寫的性能就會逐步下降。經(jīng)過我們的測試,SLC在這個方面要明顯好于MLC,在長時間寫入后,MLC隨機(jī)寫IO下降得非常厲害,而SLC表現(xiàn)則比較穩(wěn)定。為了解決這個問題,各個廠商都有很多策略來防止寫性能下降的問題。
wear leveling
因為SSD存在“寫磨損”的問題,當(dāng)某個單元長時間被反復(fù)擦寫時(比如Oracle redo),不僅會造成寫入的性能問題,而且會大大縮短SSD的使用壽命,所以必須設(shè)計一個均衡負(fù)載的算法來保證SSD的每個單元能夠被均衡的使用,這就是wear leveling,稱為損耗均衡算法。
Wear leveling也是SSD內(nèi)部的FTL實現(xiàn)的,它通過數(shù)據(jù)遷移來達(dá)到均衡損耗的目的。Wear leveling依賴于SSD中的一部分保留空間,基本原理是在SSD中設(shè)置了兩個block pool,一個是free block pool(空閑池),一個是數(shù)據(jù)池(data block pool),當(dāng)需要改寫某個page時(如果寫入原有位置,必須先擦除整個block,然后才能寫入數(shù)據(jù)),并不寫入原有位置(不需要擦除的動作),而是從空閑池中取出新的block,將現(xiàn)有的數(shù)據(jù)和需要改寫的數(shù)據(jù)合并為新的block,一起寫入新的空白block,原有的block被標(biāo)識為invalid狀態(tài)(等待被擦除回收),新的block則進(jìn)入數(shù)據(jù)池。后臺任務(wù)會定時從data block中取出無效數(shù)據(jù)的block,擦除后回收到空閑池中。這樣做的好處在于,一是不會反復(fù)擦寫同一個block,二是寫入的速度會比較快(省略了擦除的動作)。
Wear leveling分為兩種:動態(tài)損耗均衡和靜態(tài)損耗均衡,兩者的原理一致,區(qū)別在于動態(tài)算法只會處理動態(tài)數(shù)據(jù),比如數(shù)據(jù)改寫時才會觸發(fā)數(shù)據(jù)遷移的動作,對靜態(tài)數(shù)據(jù)不起作用,而靜態(tài)算法可以均衡靜態(tài)數(shù)據(jù),當(dāng)后臺任務(wù)發(fā)現(xiàn)損耗很低的靜態(tài)數(shù)據(jù)塊時,將其遷移到其他數(shù)據(jù)庫塊上,將這些塊放入空閑池中使用。從均衡的效果來看,靜態(tài)算法要好于動態(tài)算法,因為幾乎所有的block都可以被均衡的使用,SSD的壽命會大大延長,但是靜態(tài)算法的缺點(diǎn)是當(dāng)數(shù)據(jù)遷移時,可能會導(dǎo)致寫性能下降。
寫入放大
因為SSD的erase-before-write的特性,所以就出現(xiàn)了一個寫入放大的概念,比如你想改寫4K的數(shù)據(jù),必須首先將整個擦除塊(512KB)中的數(shù)據(jù)讀出到緩存中,改寫后,將整個塊一起寫入,這時你實際寫入了512KB的數(shù)據(jù),寫入放大系數(shù)是128。寫入放大***的情況是1,就是不存在放大的情況。
Wear leveling算法可以有效緩解寫入放大的問題,但是不合理的算法依然會導(dǎo)致寫入放大,比如用戶需要寫入4k數(shù)據(jù)時,發(fā)現(xiàn)free block pool中沒有空白的block,這時就必須在data block pool中選擇一個包含無效數(shù)據(jù)的block,先讀入緩存中,改寫后,將整個塊一起寫入,采用wear leveling算法依然會存在寫入放大的問題。
通過為SSD預(yù)留更多空間,可以顯著緩解寫入放大導(dǎo)致的性能問題。根據(jù)我們的測試結(jié)果,MLC SSD在長時間的隨機(jī)寫入后,性能下降很明顯(隨機(jī)寫IOPS甚至降低到300)。如果為wear leveling預(yù)留更多空間,就可以顯著改善MLC SSD在長時間寫操作之后的性能下降問題,而且保留的空間越多,性能提升就越明顯。相比較而言,SLC SSD的性能要穩(wěn)定很多(IOPS在長時間隨機(jī)寫后,隨機(jī)寫可以穩(wěn)定在3000 IOPS),我想應(yīng)該是SLC SSD的容量通常比較?。?2G和64G),而用于wear leveling的空間又比較大的原因。
數(shù)據(jù)庫IO特點(diǎn)分析
IO有四種類型:連續(xù)讀,隨機(jī)讀,隨機(jī)寫和連續(xù)寫,連續(xù)讀寫的IO size通常比較大(128KB-1MB),主要衡量吞吐量,而隨機(jī)讀寫的IO size比較小(小于8KB),主要衡量IOPS和響應(yīng)時間。數(shù)據(jù)庫中的全表掃描是連續(xù)讀IO,索引訪問則是典型的隨機(jī)讀IO,日志文件是連續(xù)寫IO,而數(shù)據(jù)文件則是隨機(jī)寫IO。
數(shù)據(jù)庫系統(tǒng)基于傳統(tǒng)磁盤訪問特性來設(shè)計,***特點(diǎn)是日志文件采用sequential logging,數(shù)據(jù)庫中的日志文件,要求必須在事務(wù)提交時寫入到磁盤,對響應(yīng)時間的要求很高,所以設(shè)計為順序?qū)懭氲姆绞?,可以有效降低磁盤尋道花費(fèi)的時間,減少延遲時間。日志文件的順序?qū)懭?,雖然是物理位置是連續(xù)的,但是并不同于傳統(tǒng)的連續(xù)寫類型,日志文件的IO size很小(通常小于4K),每個IO之間是獨(dú)立的(磁頭必須抬起來重新尋道,并等待磁盤轉(zhuǎn)動到相應(yīng)的位置),而且間隔很短,數(shù)據(jù)庫通過log buffer(緩存)和group commit的方式(批量提交)來達(dá)到提高IO size的大小,并減少IO的次數(shù),從而得到更小的響應(yīng)延遲,所以日志文件的順序?qū)懭肟梢员徽J(rèn)為是“連續(xù)位置的隨機(jī)寫入”,更關(guān)注IOPS,而不是吞吐量。
數(shù)據(jù)文件采用in place uddate的方式,意思是數(shù)據(jù)文件的修改都是寫入到原來的位置,數(shù)據(jù)文件不同于日志文件,并不會在事務(wù)commit時寫入數(shù)據(jù)文件,只有當(dāng)數(shù)據(jù)庫發(fā)現(xiàn)dirty buffer過多或者需要做checkpoint動作時,才會刷新這些dirty buffer到相應(yīng)的位置,這是一個異步的過程,通常情況下,數(shù)據(jù)文件的隨機(jī)寫入對IO的要求并不是特別高,只要滿足checkpoint和dirty buffer的要求就可以了。
SSD的IO特點(diǎn)分析
1.隨機(jī)讀能力非常好,連續(xù)讀性能一般,但比普通SAS磁盤好。
2.不存在磁盤尋道的延遲時間,隨機(jī)寫和連續(xù)寫的響應(yīng)延遲差異不大。
3.erase-before-write特性,造成寫入放大,影響寫入的性能。
4.寫磨損特性,采用wear leveling算法延長壽命,但同時會影響讀的性能。
5.讀和寫的IO響應(yīng)延遲不對等(讀要大大好于寫),而普通磁盤讀和寫的IO響應(yīng)延遲差異很小。
6.連續(xù)寫比隨機(jī)寫性能好,比如1M順序?qū)懕?28個8K的隨即寫要好很多,因為隨即寫會帶來大量的擦除。
基于SSD的上述特性,如果將數(shù)據(jù)庫全部放在SSD上,可能會有以下的問題:
1.日志文件sequential logging會反復(fù)擦寫同一位置,雖然有損耗均衡算法,但是長時間寫入依然會導(dǎo)致性能下降。
2.數(shù)據(jù)文件in place update會產(chǎn)生大量的隨機(jī)寫入,erase-before-write會產(chǎn)生寫入放大。
3.數(shù)據(jù)庫讀寫混合型應(yīng)用,存在大量的隨機(jī)寫入,同時會影響讀的性能,產(chǎn)生大量的IO延遲。
基于SSD的數(shù)據(jù)庫優(yōu)化法則:
基于SSD的優(yōu)化就是解決erase-before-write產(chǎn)生的寫入放大的問題,不同類型的IO分離,減少寫操作帶來的性能影響。
1.將sequential logging修改為In-page logging,避免對相同位置的反復(fù)擦寫。
2.通過緩存寫入的方式將大量的in-place update隨機(jī)寫入合并為少量順序?qū)懭搿?/p>
3.利用SSD隨機(jī)讀寫能力高的特點(diǎn),減少寫增加讀,從而達(dá)到整體性能的提升。
In-page logging
In-page logging是基于SSD對數(shù)據(jù)庫sequential logging的一種優(yōu)化方法,數(shù)據(jù)庫中的sequential logging對傳統(tǒng)磁盤是非常有利的,可以大大提高響應(yīng)時間,但是對于SSD就是噩夢,因為需要對同一位置反復(fù)擦寫,而wear leveling算法雖然可以平衡負(fù)載,但是依然會影響性能,并產(chǎn)生大量的IO延遲。所以In-page logging將日志和數(shù)據(jù)合并,將日志順序?qū)懭敫臑殡S機(jī)寫入,基于SSD對隨機(jī)寫和連續(xù)寫IO響應(yīng)延遲差異不大的特性,避免對同一位置反復(fù)擦寫,提高整體性能。
In-page logging基本原理:在data buffer中,有一個in-memory log sector的結(jié)構(gòu),類似于log buffer,每個log sector是與data block對應(yīng)的。在data buffer中,data和log并不合并,只是在data block和log sector之間建立了對應(yīng)關(guān)系,可以將某個data block的log分離出來。但是,在SSD底層的flash memory中,數(shù)據(jù)和日志是存放在同一個block(擦除單元),每個block都包含data page和log page。
當(dāng)日志信息需要寫入的時候(log buffer空間不足或者事務(wù)提交),日志信息會寫入到flash memory對應(yīng)的block中,也就是說日志信息是分布在很多不同的block中的,而每個block內(nèi)的日志信息是append write,所以不需要擦除的動作。當(dāng)某個block中的log sector寫滿的時候,這時會發(fā)生一個動作,將整個block中的信息讀出,然后應(yīng)用block中的log sector,就可以得到***的數(shù)據(jù),然后整個block寫入,這時,block中的log sector是空白的。
在in-page logging方法中,data buffer中的dirty block是不需要寫入到flash memory中的,就算dirty buffer需要被交換出去,也不需要將它們寫入flash memory中。當(dāng)需要讀取***的數(shù)據(jù),只要將block中的數(shù)據(jù)和日志信息合并,就可以得到***的數(shù)據(jù)。
In-page logging方法,將日志和數(shù)據(jù)放在同一個擦除單元內(nèi),減少了對flash相同位置的反復(fù)擦寫,而且不需要將dirty block寫入到flash中,大量減少了in-place update的隨機(jī)寫入和擦除的動作。雖然在讀取時,需要做一個merge的操作,但是因為數(shù)據(jù)和日志存放在一起,而且SSD的隨機(jī)讀取能力很高,in-page logging可以提高整體的性能。
SSD作為寫cache-append write
SSD可以作為磁盤的寫cache,因為SSD連續(xù)寫比隨機(jī)寫性能好,比如:1M順序?qū)懕?28個8K的隨機(jī)寫要好很多,我們可以將大量隨機(jī)寫合并成為少量順序?qū)?,增加IO的大小,減少IO(擦除)的次數(shù),提高寫入性能。這個方法與很多NoSQL產(chǎn)品的append write類似,即不改寫數(shù)據(jù),只追加數(shù)據(jù),需要時做合并處理。
基本原理:當(dāng)dirty block需要寫入到數(shù)據(jù)文件時,并不直接更新原來的數(shù)據(jù)文件,而是首先進(jìn)行IO合并,將很多個8K的dirty block合并為一個512KB的寫入單元,并采用append write的方式寫入到一個cache file中(保存在SSD上),避免了擦除的動作,提高了寫入性能。cache file中的數(shù)據(jù)采用循環(huán)的方式順序?qū)懭?,?dāng)cache file空間不足夠時,后臺進(jìn)程會將cache file中的數(shù)據(jù)寫入到真正的數(shù)據(jù)文件中(保存在磁盤上),這時進(jìn)行第二次IO合并,將cache file內(nèi)的數(shù)據(jù)進(jìn)行合并,整合成為少量的順序?qū)懭?,對于磁盤來說,最終的IO是1M的順序?qū)懭?,順序?qū)懭胫粫绊懲掏铝浚疟P的吞吐量不會成為瓶頸,將IOPS的瓶頸轉(zhuǎn)化為吞吐量的瓶頸,從而提升了整體系統(tǒng)能力。
讀取數(shù)據(jù)時,必須首先讀取cache file,而cache file中的數(shù)據(jù)是無序存放的,為了快速檢索cache file中的數(shù)據(jù),一般會在內(nèi)存中為cache file建立一個索引,讀取數(shù)據(jù)時會先查詢這個索引,如果命中查詢cache file,如果沒有命中,再讀取data file(普通磁盤),所以,這種方法實際不僅僅是寫cache,同時也起到了讀cache的作用。
但是這種方法并不適合日志文件的寫cache,雖然日志文件也是append write,但是因為日志文件的IO size比較小,而且必須同步寫入,無法做合并處理,所以性能提升有限。
SSD作為讀cache-flashcache
因為大部分?jǐn)?shù)據(jù)庫都是讀多寫少的類型,所以SSD作為數(shù)據(jù)庫flashcache是優(yōu)化方案中最簡單的一種,它可以充分利用SSD讀性能的優(yōu)勢,又避免了SSD寫入的性能問題。實現(xiàn)的方法有很多種,可以在讀取數(shù)據(jù)時,將數(shù)據(jù)同時寫入SSD,也可以在數(shù)據(jù)被刷出buffer時,寫入到SSD。讀取數(shù)據(jù)時,首先在buffer中查詢,然后在flashcache中查詢,***讀取datafile。
SSD作為flashcache與memcache作為數(shù)據(jù)庫外部cache的***區(qū)別在于,SSD掉電后數(shù)據(jù)是不丟失的,這也引起了另外一個思考,當(dāng)數(shù)據(jù)庫發(fā)生故障重啟后,flashcache中的數(shù)據(jù)是有效還是無效?如果是有效的,那么就必須時刻保證flashcache中數(shù)據(jù)的一致性,如果是無效的,那么flashcache同樣面臨一個預(yù)熱的問題(這與memcache掉電后的問題一樣)。目前,據(jù)我所知,基本上都認(rèn)為是無效的,因為要保持flashcache中數(shù)據(jù)的一致性,非常困難。
flashcache作為內(nèi)存和磁盤之間的二級cache,除了性能的提升以外,從成本的角度看,SSD的價格介于memory和disk之間,作為兩者之間的一層cache,可以在性能和價格之間找到平衡。
總結(jié)
隨著SSD價格不斷降低,容量和性能不斷提升,SSD取代磁盤只是個時間問題。
原文鏈接:http://www.hellodba.net/2010/10/ssd-database-2.html
【編輯推薦】