SSD技術特點

NOR和NAND都是閃存技術的一種,NOR是Intel公司開發的,它有點類似於內存,允許通過地址直接訪問任何一個內存單元,缺點是:密度低(容量小),寫入和擦除的速度很慢。NAND是東芝公司開發的,它密度高(容量大),寫入和擦除的速度都很快,但是必須通過特定的IO接口經過地址轉換之後纔可以訪問,有些類似於磁盤。

我們現在廣泛使用的U盤,SD卡,SSD都屬於NAND類型,廠商將flash memory封裝成爲不同的接口,比如Intel的SSD就是採用了SATA的接口,訪問與普通SATA磁盤一樣,還有一些企業級的閃存卡,比如FusionIO,則封裝爲PCIe接口。

SLC和MLC

SLC是單極單元,MLC是多級單元,兩者的差異在於每單元存儲的數據量(密度),SLC每單元只存儲一位,只包含0和1兩個電壓符,MLC每單元可以存儲兩位,包含四個電壓符(00,01,10,11)。顯然,MLC的存儲容量比SLC大,但是SLC更簡單可靠,SLC讀取和寫入的速度都比MLC更快,而且SLC比MLC更耐用,MLC每單元可擦除1w次,而SLC可擦除10w次,所以,企業級的閃存產品一般都選用SLC,這也是爲什麼企業級產品比家用產品貴很多的原因。

SSD的技術特點

SSD與傳統磁盤相比,第一是沒有機械裝置,第二是由磁介質改爲了電介質。在SSD內部有一個FTL(Flash Transalation Layer),它相當於磁盤中的控制器,主要功能就是作地址映射,將flash memory的物理地址映射爲磁盤的LBA邏輯地址,並提供給OS作透明訪問。

SSD沒有傳統磁盤的尋道時間和延遲時間,所以SSD可以提供非常高的隨機讀取能力,這是它的最大優勢,SLC類型的SSD通常可以提供超過35000的IOPS,傳統15k的SAS磁盤,最多也只能達到160個IOPS,這對於傳統磁盤來說幾乎就是個天文數字。SSD連續讀的能力相比普通磁盤優勢並不明顯,因爲連續讀對於傳統磁盤來說,並不需要尋道時間,15k的SAS磁盤,連續讀的吞吐能力可以達到130MB,而SLC類型的SSD可以達到170-200MB,我們看到在吞吐量方面,SSD雖然比傳統磁盤高一些,但優勢雖然並不明顯。

SSD的寫操作比較特殊,SSD的最小寫入單元爲4KB,稱爲頁(page),當寫入空白位置時可以按照4KB的單位寫入,但是如果需要改寫某個單元時,則需要一個額外的擦除(erase)動作,擦除的單位一般是128個page(512KB),每個擦除單元稱爲塊(block)。如果向一個空白的page寫入信息時,可以直接寫入而無需擦除,但是如果需要改寫某個存儲單元(page)的數據,必須首先將整個block讀入緩存,然後修改數據,並擦除整個block的數據,最後將整個block寫入,很顯然,SSD改寫數據的代價很高,SSD的這個特性,我們稱之爲erase-before-write。

經過測試,SLC SSD的隨即寫性能可以達到3000個左右的IOPS,連續寫的吞吐量可以達到170-200MB,這個數據還是比傳統磁盤高出不少。但是,隨着SSD的不斷寫入,當越來越多的數據需要被改寫時,寫的性能就會逐步下降。經過我們的測試,SLC在這個方面要明顯好於MLC,在長時間寫入後,MLC隨機寫IO下降得非常厲害,而SLC表現則比較穩定。爲了解決這個問題,各個廠商都有很多策略來防止寫性能下降的問題。

wear leveling

因爲SSD存在“寫磨損”的問題,當某個單元長時間被反覆擦寫時(比如Oracle redo),不僅會造成寫入的性能問題,而且會大大縮短SSD的使用壽命,所以必須設計一個均衡負載的算法來保證SSD的每個單元能夠被均衡的使用,這就是wear leveling,稱爲損耗均衡算法。

Wear leveling也是SSD內部的FTL實現的,它通過數據遷移來達到均衡損耗的目的。Wear leveling依賴於SSD中的一部分保留空間,基本原理是在SSD中設置了兩個block pool,一個是free block pool(空閒池),一個是數據池(data block pool),當需要改寫某個page時(如果寫入原有位置,必須先擦除整個block,然後才能寫入數據),並不寫入原有位置(不需要擦除的動作),而是從空閒池中取出新的block,將現有的數據和需要改寫的數據合併爲新的block,一起寫入新的空白block,原有的block被標識爲invalid狀態(等待被擦除回收),新的block則進入數據池。後臺任務會定時從data block中取出無效數據的block,擦除後回收到空閒池中。這樣做的好處在於,一是不會反覆擦寫同一個block,二是寫入的速度會比較快(省略了擦除的動作)。

 

Wear leveling分爲兩種:動態損耗均衡和靜態損耗均衡,兩者的原理一致,區別在於動態算法只會處理動態數據,比如數據改寫時纔會觸發數據遷移的動作,對靜態數據不起作用,而靜態算法可以均衡靜態數據,當後臺任務發現損耗很低的靜態數據塊時,將其遷移到其他數據庫塊上,將這些塊放入空閒池中使用。從均衡的效果來看,靜態算法要好於動態算法,因爲幾乎所有的block都可以被均衡的使用,SSD的壽命會大大延長,但是靜態算法的缺點是當數據遷移時,可能會導致寫性能下降。

寫入放大

因爲SSD的erase-before-write的特性,所以就出現了一個寫入放大的概念,比如你想改寫4K的數據,必須首先將整個擦除塊(512KB)中的數據讀出到緩存中,改寫後,將整個塊一起寫入,這時你實際寫入了512KB的數據,寫入放大係數是128。寫入放大最好的情況是1,就是不存在放大的情況。

Wear leveling算法可以有效緩解寫入放大的問題,但是不合理的算法依然會導致寫入放大,比如用戶需要寫入4k數據時,發現free block pool中沒有空白的block,這時就必須在data block pool中選擇一個包含無效數據的block,先讀入緩存中,改寫後,將整個塊一起寫入,採用wear leveling算法依然會存在寫入放大的問題。

通過爲SSD預留更多空間,可以顯著緩解寫入放大導致的性能問題。根據我們的測試結果,MLC SSD在長時間的隨機寫入後,性能下降很明顯(隨機寫IOPS甚至降低到300)。如果爲wear leveling預留更多空間,就可以顯著改善MLC SSD在長時間寫操作之後的性能下降問題,而且保留的空間越多,性能提升就越明顯。相比較而言,SLC SSD的性能要穩定很多(IOPS在長時間隨機寫後,隨機寫可以穩定在3000 IOPS),我想應該是SLC SSD的容量通常比較小(32G和64G),而用於wear leveling的空間又比較大的原因。

數據庫IO特點分析

IO有四種類型:連續讀,隨機讀,隨機寫和連續寫,連續讀寫的IO size通常比較大(128KB-1MB),主要衡量吞吐量,而隨機讀寫的IO size比較小(小於8KB),主要衡量IOPS和響應時間。數據庫中的全表掃描是連續讀IO,索引訪問則是典型的隨機讀IO,日誌文件是連續寫IO,而數據文件則是隨機寫IO。

數據庫系統基於傳統磁盤訪問特性來設計,最大特點是日誌文件採用sequential logging,數據庫中的日誌文件,要求必須在事務提交時寫入到磁盤,對響應時間的要求很高,所以設計爲順序寫入的方式,可以有效降低磁盤尋道花費的時間,減少延遲時間。日誌文件的順序寫入,雖然是物理位置是連續的,但是並不同於傳統的連續寫類型,日誌文件的IO size很小(通常小於4K),每個IO之間是獨立的(磁頭必須擡起來重新尋道,並等待磁盤轉動到相應的位置),而且間隔很短,數據庫通過log buffer(緩存)和group commit的方式(批量提交)來達到提高IO size的大小,並減少IO的次數,從而得到更小的響應延遲,所以日誌文件的順序寫入可以被認爲是“連續位置的隨機寫入”,瓶頸還是在IOPS,而不是吞吐量。

數據文件採用in place update的方式,意思是數據文件的修改都是寫入到原來的位置,數據文件不同於日誌文件,並不會在事務commit時寫入數據文件,只有當數據庫發現dirty buffer過多或者需要做checkpoint動作時,纔會刷新這些dirty buffer到相應的位置,這是一個異步的過程,通常情況下,數據文件的隨機寫入對IO的要求並不是特別高,只要滿足checkpoint和dirty buffer的要求就可以了。

SSD的IO特點分析

1.隨機讀能力非常好,連續讀性能一般,但比普通SAS磁盤好。

2.不存在磁盤尋道的延遲時間,隨機寫和連續寫的響應延遲差異不大。

3.erase-before-write特性,造成寫入放大,影響寫入的性能。

4.寫磨損特性,採用wear leveling算法延長壽命,但同時會影響讀的性能。

5.讀和寫的IO響應延遲不對等(讀要大大好於寫),而普通磁盤讀和寫的IO響應延遲差異很小。

6.連續寫比隨機寫性能好,比如1M順序寫比128個8K的隨即寫要好很多,因爲隨即寫會帶來大量的擦除。

基於SSD的上述特性,如果將數據庫全部放在SSD上,可能會有以下的問題:

1.日誌文件sequential logging會反覆擦寫同一位置,雖然有損耗均衡算法,但是長時間寫入依然會導致性能下降。

2.數據文件in place update會產生大量的隨機寫入,erase-before-write會產生寫入放大。

3.數據庫讀寫混合型應用,存在大量的隨機寫入,同時會影響讀的性能,產生大量的IO延遲。

基於SSD的數據庫優化法則

基於SSD的優化就是解決erase-before-write產生的寫入放大的問題,不同類型的IO分離,減少寫操作帶來的性能影響。

1.將sequential logging修改爲In-page logging,避免對相同位置的反覆擦寫。

2.通過緩存寫入的方式將大量的in-place update隨機寫入合併爲少量順序寫入。

3.利用SSD隨機讀寫能力高的特點,減少寫增加讀,從而達到整體性能的提升。

In-page logging

In-page logging是基於SSD對數據庫sequential logging的一種優化方法,數據庫中的sequential logging對傳統磁盤是非常有利的,可以大大提高響應時間,但是對於SSD就是噩夢,因爲需要對同一位置反覆擦寫,而wear leveling算法雖然可以平衡負載,但是依然會影響性能,併產生大量的IO延遲。所以In-page logging將日誌和數據合併,將日誌順序寫入改爲隨機寫入,基於SSD對隨機寫和連續寫IO響應延遲差異不大的特性,避免對同一位置反覆擦寫,提高整體性能。

In-page logging基本原理:在data buffer中,有一個in-memory log sector的結構,類似於log buffer,每個log sector是與data block對應的。在data buffer中,data和log並不合併,只是在data block和log sector之間建立了對應關係,可以將某個data block的log分離出來。但是,在SSD底層的flash memory中,數據和日誌是存放在同一個block(擦除單元),每個block都包含data page和log page。

當日志信息需要寫入的時候(log buffer空間不足或者事務提交),日誌信息會寫入到flash memory對應的block中,也就是說日誌信息是分佈在很多不同的block中的,而每個block內的日誌信息是append write,所以不需要擦除的動作。當某個block中的log sector寫滿的時候,這時會發生一個動作,將整個block中的信息讀出,然後應用block中的log sector,就可以得到最新的數據,然後整個block寫入,這時,block中的log sector是空白的。

在in-page logging方法中,data buffer中的dirty block是不需要寫入到flash memory中的,就算dirty buffer需要被交換出去,也不需要將它們寫入flash memory中。當需要讀取最新的數據,只要將block中的數據和日誌信息合併,就可以得到最新的數據。

In-page logging方法,將日誌和數據放在同一個擦除單元內,減少了對flash相同位置的反覆擦寫,而且不需要將dirty block寫入到flash中,大量減少了in-place update的隨機寫入和擦除的動作。雖然在讀取時,需要做一個merge的操作,但是因爲數據和日誌存放在一起,而且SSD的隨機讀取能力很高,in-page logging可以提高整體的性能。

 

SSD作爲寫cache—append write

SSD可以作爲磁盤的寫cache,因爲SSD連續寫比隨機寫性能好,比如:1M順序寫比128個8K的隨機寫要好很多,我們可以將大量隨機寫合併成爲少量順序寫,增加IO的大小,減少IO(擦除)的次數,提高寫入性能。這個方法與很多NoSQL產品的append write類似,即不改寫數據,只追加數據,需要時做合併處理。

基本原理:當dirty block需要寫入到數據文件時,並不直接更新原來的數據文件,而是首先進行IO合併,將很多個8K的dirty block合併爲一個512KB的寫入單元,並採用append write的方式寫入到一個cache file中(保存在SSD上),避免了擦除的動作,提高了寫入性能。cache file中的數據採用循環的方式順序寫入,當cache file空間不足夠時,後臺進程會將cache file中的數據寫入到真正的數據文件中(保存在磁盤上),這時進行第二次IO合併,將cache file內的數據進行合併,整合成爲少量的順序寫入,對於磁盤來說,最終的IO是1M的順序寫入,順序寫入只會影響吞吐量,而磁盤的吞吐量不會成爲瓶頸,將IOPS的瓶頸轉化爲吞吐量的瓶頸,從而提升了整體系統能力。

讀取數據時,必須首先讀取cache file,而cache file中的數據是無序存放的,爲了快速檢索cache file中的數據,一般會在內存中爲cache file建立一個索引,讀取數據時會先查詢這個索引,如果命中查詢cache file,如果沒有命中,再讀取data file(普通磁盤),所以,這種方法實際不僅僅是寫cache,同時也起到了讀cache的作用。

SSD並不適合放數據庫的日誌文件,雖然日誌文件也是append write,但是因爲日誌文件的IO size比較小,而且必須同步寫入,無法做合併處理,對SSD來說,需要大量的擦除動作。我們也曾經嘗試把redo log放在SSD上,考慮到SSD的隨機寫入也可以達到3000 IOPS,而且響應延時比磁盤低很多,但是這依賴於SSD本身的wear leveling算法是否優秀,而且日誌文件必須是獨立存放的,如果日誌文件的寫入是瓶頸,也算是一種解決方案吧。通常情況下,我還是建議日誌文件放在普通磁盤上,而不是SSD。

SSD作爲讀cache—flashcache

因爲大部分數據庫都是讀多寫少的類型,所以SSD作爲數據庫flashcache是優化方案中最簡單的一種,它可以充分利用SSD讀性能的優勢,又避免了SSD寫入的性能問題。實現的方法有很多種,可以在讀取數據時,將數據同時寫入SSD,也可以在數據被刷出buffer時,寫入到SSD。讀取數據時,首先在buffer中查詢,然後在flashcache中查詢,最後讀取datafile。

SSD作爲flashcache與memcache作爲數據庫外部cache的最大區別在於,SSD掉電後數據是不丟失的,這也引起了另外一個思考,當數據庫發生故障重啓後,flashcache中的數據是有效還是無效?如果是有效的,那麼就必須時刻保證flashcache中數據的一致性,如果是無效的,那麼flashcache同樣面臨一個預熱的問題(這與memcache掉電後的問題一樣)。目前,據我所知,基本上都認爲是無效的,因爲要保持flashcache中數據的一致性,非常困難。

flashcache作爲內存和磁盤之間的二級cache,除了性能的提升以外,從成本的角度看,SSD的價格介於memory和disk之間,作爲兩者之間的一層cache,可以在性能和價格之間找到平衡。

總結

隨着SSD價格不斷降低,容量和性能不斷提升,SSD取代磁盤只是個時間問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章