介紹
SSD是目前商用伺服器上非常流行的儲存介質,因此,作為軟體開發人員,需要了解的SSD基本原理,以便開發時能更好地發揮其優勢,規避其劣勢。本文總結了作為軟體開發人員需要了解的SSD基本原理,全文組織結構如下:
- SSD的讀寫速度
- SSD內部晶片的簡單存取原理
- SSD的讀寫特性
- SSD的over-provisioning和garbage-collection
- SSD的損耗均衡控制
- SSD的寫放大問題
本文同步釋出在個人部落格oserror.com。
SSD的讀寫速度
首先,從軟體開發人員作為SSD的使用者角度來講,首先需要了解的是SSD和普通HDD的效能對比,如下:
先來看順序讀和順序寫
其中,Seagate ST3000DM001是HDD,其他的都是SSD。從上述兩圖中可以看出,HDD的順序讀速度差不多為最慢的SSD的一半,順序寫稍微好點,但也比大部分慢一倍左右的速度。
再來看隨機讀和隨機寫
可以看出,HDD的隨機讀的效能是普通SSD的幾十分之一,隨機寫效能更差。
因此,SSD的隨機讀和寫效能要遠遠好於HDD,本文接下來的幾個小節將會討論為什麼SSD的隨機讀寫效能要遠遠高於HDD?
備註:本小節測試資料全部來自於HDD VS SSD。
SSD內部晶片的簡單儲存原理
SSD內部一般使用NAND Flash來作為儲存介質,其邏輯結構如下:
SSD中一般有多個NAND Flash,每個NAND Flash包含多個Block,每個Block包含多個Page。由於NAND的特性,其存取都必須以page為單位,即每次讀寫至少是一個page,通常地,每個page的大小為4k或者8k。另外,NAND還有一個特性是,其只能是讀或寫單個page,但不能覆蓋寫如某個page,必須先要清空裡面的內容,再寫入。由於清空內容的電壓較高,必須是以block為單位。因此,沒有空閒的page時,必須要找到沒有有效內容的block,先擦寫,然後再選擇空閒的page寫入。
在SSD中,一般會維護一個mapping table,維護邏輯地址到實體地址的對映。每次讀寫時,可以通過邏輯地址直接查表計算出實體地址,與傳統的機械磁碟相比,省去了尋道時間和旋轉時間。
SSD讀寫特性
從NAND Flash的原理可以看出,其和HDD的主要區別為
- 定位資料快:HDD需要經過尋道和旋轉,才能定位到要讀寫的資料塊,而SSD通過mapping table直接計算即可
- 讀取速度塊:HDD的速度取決於旋轉速度,而SSD只需要加電壓讀取資料,一般而言,要快於HDD
因此,在順序讀測試中,由於定位資料只需要一次,定位之後,則是大批量的讀取資料的過程,此時,HDD和SSD的效能差距主要體現在讀取速度上,HDD能到200M左右,而普通SSD是其兩倍。
在隨機讀測試中,由於每次讀都要先定位資料,然後再讀取,HDD的定位資料的耗費時間很多,一般是幾毫秒到十幾毫秒,遠遠高於SSD的定位資料時間(一般0.1ms左右),因此,隨機讀寫測試主要體現在兩者定位資料的速度上,此時,SSD的效能是要遠遠好於HDD的。
對於SSD的寫操作,針對不同的情況,有不同的處理流程,主要是受到NAND Flash的如下特性限制
- NAND Flash每次寫必須以page為單位,且只能寫入空閒的page,不能覆蓋寫原先有內容的page
- 擦除資料時,由於電壓較高,只能以block為單位擦除
SSD的寫分為新寫入和更新兩種,處理流程不同。
先看新寫入的資料的流程,如下:
假設新寫入了一個page,其流程如下:
- 找到一個空閒page
- 把資料寫入到空閒page中
- 更新mapping table
而更新操作的流程如下:
假設是更新了page G中的某些位元組,流程如下:
- 由於SSD不能覆蓋寫,因此,先找到一個空閒頁H
- 讀取page G中的資料到SSD內部的buffer中,把更新的位元組更新到buffer
- 把buffer中的資料寫入到H
- 更新mapping table中G頁,置為無效頁
- 更新mapping table中H頁,新增對映關係
可以看出,如果在更新操作比較多的情況下,會產生較多的無效頁,類似於磁碟碎片,此時,需要SSD的over-provisioning和garbage-collection。
SSD的over-provisioning和garbage-collection
over-provisioning是指SSD實際的儲存空間比可寫入的空間要大,比如,一塊可用容量為120G的SSD,實際空間可能有128G。為什麼需要over-provisioning呢?請看如下例子:
如上圖所示,假設系統中就兩個block,最終還剩下兩個無效的page,此時,要寫入一個新page,根據NAND原理,必須要先對兩個無效的page擦除才能用於寫入。此時,就需要用到SSD提供的額外空間,才能用garbage-collection方法整理出可用空間。
garbage collection的整理流程如上圖所示
- 首先,從over-provisoning的空間中,找到一個空閒的block
- 把Block0的ABCDEFH和Block1的A複製到空閒block
- 擦除Block 0
- 把Block1的BCDEFH複製到Block0,此時Block0就有兩個空閒page了
- 擦除BLock1
有空閒page之後,就可以按照正常的流程來寫入了。
SSD的garbage-collection會帶來兩個問題:
- SSD的壽命減少,NAND Flash中每個原件都有擦寫次數限制,超過一定擦寫次數後,就只能讀取不能寫入了
- 寫放大問題,即內部真正寫入的資料量大於使用者請求寫入的資料量
如果頻繁的在某些block上做garbage-collection,會使得這些元件比其他部分更快到達擦寫次數限制,因此,需要某個演算法,能使得原件的擦寫次數比較平均,這樣才能延長SSD的壽命,這就需要下面要討論的損耗均衡控制了。
SSD損耗均衡控制
為了避免某些block被頻繁的更新,而另外一些block非常的空閒,SSD控制器一般會記錄各個block的寫入次數,並且通過一定的演算法,來達到每個block的寫入都比較均衡。
以一個例子,說明損耗均衡控制的重要性:
假如一個NAND Flash總共有4096個block,每個block的擦寫次數最大為10000。其中有3個檔案,每個檔案佔用50個block,平均10分鐘更新1個檔案,假設沒有均衡控制,那麼只會3 * 50 + 50共200個block,則這個SSD的壽命如下:
大約為278天。而如果是完美的損耗均衡控制,即4096個block都均衡地參與更新,則使用壽命如下:
大約5689天。因此,設計一個好的損耗均衡控制演算法是非常有必要的,主流的方法主要有兩種:
- dynamic wear leveling
- static wear leveling
這裡的dynamic和static是指的是資料的特性,如果資料頻繁的更新,那麼資料是dynamic的,如果資料寫入後,不更新,那麼是static的。
dynamic wear leveling的原理是記錄每個block的擦寫次數,每次寫入資料時,找到被擦除次數最小的空block。
static wear leveling的原理分為兩塊:
- 每次找到每擦除次數最小的可用block
- 當某個block的擦除次數小於閾值時,會將它與擦寫次數較高的block的資料進行交換
以一個例子來說明,兩種擦寫演算法的不同點:
假如SSD中有25%的資料是dynamic的,另外75%的資料是static的。對於dynamic wear leveling方法,每次要找的是擦除了資料的block,而static的block裡面是有資料的,因此,每次都只會在dynamic的block中,即最多會在25%的block中做均衡;對於static演算法,每次找的block既可能是dynamic的,也可能是static的,因此,最多有可能在全部的block中做均衡。
相對而言,static演算法能使得SSD的壽命更長,但也有其缺點:
- 演算法邏輯更復雜
- 在寫入時,可能會移動資料,導致寫放大,降低寫入效能
- 更高的能耗
SSD寫放大
最後,我們分析一下SSD的寫放大問題,一般由如下三個方面引起:
- SSD讀寫是以page為單位的,如果更新page中的部分資料,也需要寫整個page
- SSD的garbage collection中,會在block間移動資料
- SSD的wear leveing中,可能也會在block間交換資料,導致寫放大
通常的,需要在其他方面和SSD的寫放大之間做權衡,例如,可以減少garbage collection的頻率來減少寫放大問題;可以把SSD分成多個zone,每個zone使用不同的wear leveling方法等等。
總結
個人理解,使用SSD時,我們需要考慮如下情況:
- 需要充分利用其隨機讀寫快的特性
- 儘可能在軟體層面更新小塊資料,減輕SSD寫放大問題
- 避免頻繁的更新資料,減輕SSD寫放大及壽命減少的問題,儘可能使用追加的方式寫資料
PS:
本部落格更新會在第一時間推送到微信公眾號,歡迎大家關注。