1. 程式人生 > >SSD背後的祕密:SSD基本工作原理

SSD背後的祕密:SSD基本工作原理

SSD主要由SSD控制器,FLASH儲存陣列,板上DRAM(可選),以及跟HOST介面(諸如SATA,SAS, PCIe等)組成。

SSD主控通過若干個通道(channel)並行操作多塊FLASH顆粒,類似RAID0,大大提高底層的頻寬。舉個例子,假設主控與FLASH顆粒之間有8個通道,每個通道上掛載了一個快閃記憶體顆粒,HOST與FLASH之間資料傳輸速率為200MB/s。該快閃記憶體顆粒Page大小為8KB,FLASH page的讀取時間為Tr=50us,平均寫入時間為Tp=800us,8KB資料傳輸時間為Tx=40us。那麼底層讀取最大頻寬為(8KB/(50us+40us))*8 = 711MB/s,寫入最大頻寬為(8KB/(800us+40us))*8 = 76MB/s。從上可以看出,要提高底層頻寬,可以增加底層並行的顆粒數目,也可以選擇速度快的FLASH顆粒(或者讓速度慢的顆粒變快,比如MLC配成SLC使用)。

我們以8通道為例,來講講HOST怎麼讀寫SSD。主控通過8通道連線8個FLASH DIE,為方便解釋,這裡只畫了每個DIE裡的一個Block,其中每個小方塊表示一個Page (假設大小為4KB)。

  1. HOST寫入4KB資料

  1. HOST繼續寫入16KB資料

  1. HOST繼續寫入,最後整個Block都寫滿

當所有Channel上的Block都寫滿的時候,SSD主控會挑選下一個Block以同樣的方式繼續寫入。

HOST是通過LBA(Logical Block Address,邏輯地址塊)訪問SSD的,每個LBA代表著一個Sector(一般為512B大小),作業系統一般以4K為單位訪問SSD,我們把HOST訪問SSD的基本單元叫使用者頁(Host Page)。而在SSD內部,SSD主控與FLASH之間是FLASH Page為基本單元訪問FLASH的,我們稱FLASH Page為物理頁(Physical Page)。HOST每寫入一個Host Page, SSD主控會找一個Physical Page把Host資料寫入,SSD內部同時記錄了這樣一條對映(Map)。有了這樣一個對映關係後,下次HOST需要讀某個Host Page 時,SSD就知道從FLASH的哪個位置把資料讀取上來。

SSD內部維護了一張對映表(Map Table),HOST每寫入一個Host Page,就會產生一個新的對映關係,這個對映關係會加入(第一次寫)或者更改(覆蓋寫)Map Table;當讀取某個Host Page時, SSD首先查詢Map Table中該Host Page對應的Physical Page,然後再訪問Flash讀取相應的Host資料。

一張Map Table有多大呢?這裡假設我們有一個256GB的SSD,以4KB Host Page為例,那麼一共有約 64M(256GB/4KB)個Host Page,也就意味著SSD需要有64M大小的Map Table。Map Table中的每個Entry儲存的就是實體地址(Physical Page Address),假設其為4Byte (32 bits) ,那麼整個Map Table的大小為64M*4B = 256MB。

對絕大多數SSD,我們可以看到上面都有板載DRAM,其主要作用就是用來儲存這張對映表。也有例外,比如基於Sandforce主控的SSD,它並不支援板載DRAM,那麼它的對映表存在哪裡呢?SSD工作時,它的絕大部分對映是儲存在FLASH裡面,還有一部分儲存在片上RAM上。當HOST需要讀取一筆資料時,對有板載DRAM的SSD來說,只要查詢DRAM當中的對映表,獲取到實體地址後訪問FLASH從而得到HOST資料.這期間只需要訪問一次FLASH;而對Sandforce的SSD來說,它首先看看該Host Page對應的對映關係是否在RAM內,如果在,那好辦,直接根據對映關係讀取FLASH;如果該對映關係不在RAM內,那麼它首先需要把對映關係從FLASH裡面讀取出來,然後再根據這個對映關係讀取Host資料,這就意味著相比有DRAM的SSD,它需要讀取兩次FLASH才能把HOST資料讀取出來,底層有效頻寬減半。對HOST隨機讀來說,由於片上RAM有限,對映關係Cache命中(對映關係在片上RAM)的概率很小,所以對它來說,基本每次讀都需要訪問兩次FLASH,所以我們可以看到基於Sandforce主控的SSD隨機讀取效能是不太理想的。

繼續回到之前的SSD寫操作。當整個SSD寫滿後,從使用者角度來看,如果想寫入新的資料,則必須刪除一些資料,然後騰出空間再寫。使用者在刪除和寫入資料的過程中,會導致一些Block裡面的資料變無效或者變老。如下圖所示(綠色小方塊代表有效資料,紅色小方塊代表無效資料):

Block中的資料變老或者無效,是指沒有任何對映關係指向它們,使用者不會訪問到這些FLASH空間,它們被新的對映關係所取代。比如有一個Host Page A,開始它儲存在FLASH空間的X,對映關係為A->X。後來,HOST重寫了該Host Page,由於FLASH不能覆蓋寫,SSD內部必須尋找一個沒有寫過的位置寫入新的資料,假設為Y,這個時候新的對映關係建立:A->Y,之前的對映關係解除,位置X上的資料變老失效,我們把這些資料叫垃圾資料。

隨著HOST的持續寫入,FLASH儲存空間慢慢變小,直到耗盡。如果不及時清除這些垃圾資料,HOST就無法寫入。SSD內部都有垃圾回收機制,它的基本原理是把幾個Block中的有效資料(非垃圾資料,上圖中的綠色小方塊表示的)集中搬到一個新的Block上面去,然後再把這幾個Block擦除掉,這樣就產生新的可用Block了。

上圖中,Block x上面有效資料為A,B,C,Block y上面有效資料為D,E,F,G,紅色方塊為無效資料。垃圾回收機制就是先找一個未寫過的可用Block z,然後把Block x和Block y的有效資料搬移到Block z上面去,這樣Block x和Block y上面就沒有任何有效資料,可以擦除變成兩個可用的Block。

一塊剛買的SSD,你會發現寫入速度很快,那是因為一開始總能找到可用的Block來進行寫入。但是,隨著你對SSD的使用,你會發現它會變慢。原因就在於SSD寫滿後,當你需要寫入新的資料,往往需要做上述的垃圾回收:把若干個Block上面的有效資料搬移到某個Block,然後擦掉原先的Block,然後再把你的Host資料寫入。這比最初單純的找個可用的Block來寫耗時多了,所以速度變慢也就可以理解了。

還是以上圖為例。假設HOST要寫入4KB資料 (H) ,由於當前可用Block過少,SSD開始做垃圾回收。從上圖可以看出,對Block x來說,它需要把Page A,B,C的資料讀出並寫入到Block z,然後Block x擦除用於HOST資料寫入。從Host角度,它只寫了4KB資料,但從SSD內部來說,它實際寫入了4個Page(Page A, B, C寫入Block z,4KB資料H寫入到Block x)。

2008年,Intel公司和SiliconSystems公司(2009 年被西部數字收購)第一次提出了寫入放大(Write Amplification)並在公開稿件裡用到這個術語。

在上面例子中,Host寫了4KB資料,快閃記憶體寫了4個4KB資料,所以上面例子中寫放大為4。

對空盤來說,寫放大一般為1,即Host寫入多少資料,寫入FLASH也是多少資料量。在Sandforce控制器出來之前,寫放大最小值為1。但是由於Sandforce內部具有壓縮模組,它能對Host寫入的資料進行實時壓縮,然後再把它們寫入到NAND。舉個例子,HOST寫入8KB資料,經壓縮後,資料變為4KB,如果這個時候還沒有垃圾回收,那麼寫放大就只有0.5。Intel之前說寫放大不可能小於1,但Sandforce打破了這個說法。

說完寫放大,再談談預留空間(OP, Over Provisioning)。

假設一個SSD,底下所有FLASH容量為256GB,開放給使用者使用也是256GB,那麼問題就來了。想象一個場景,HOST持續寫滿整個SSD,接著刪除一些檔案,寫入新的檔案資料,試問新的資料能寫入嗎?在SSD底層,如果要寫入新的資料,必須要有可用的空閒Block,但由於之前256GB空間已經被HOST資料佔用了,根本就沒有空閒Block來寫你的資料。不對,你剛才不是刪了一些資料嗎?你可以垃圾回收呀。不錯,但問題來了,在上面介紹垃圾回收的時候,我們需要有Block z來寫回收來的有效資料,我們這個時候連Block z都找不到,談什麼垃圾回收?所以,最後是使用者寫失敗。

上面這個場景至少說明了一點,SSD內部需要預留空間(需要有自己的小金庫,不能工資全部上繳),這部分空間HOST是看不到的。這部分預留空間,不僅僅用以做垃圾回收,事實上,SSD內部的一些系統資料,也需要預留空間來儲存,比如前面說到的對映表(Map Table),比如SSD韌體,以及其它的一些SSD系統管理資料。

一般從HOST角度來看,1GB= 1,000,000,000Byte,從底層FLASH角度,1GB=1*1024*1024*1024Byte。256GB FLASH 為256*(2^30) Byte,而一般說的256GB SSD 容量為256*(10^9) Byte,這樣,天然的有(256*(2^30)-256*(10^9))/(256*(10^9)) = 7.37%的OP。

如果把256GB Flash容量的SSD配成240GB的,那麼它的OP是多大呢?

(256*(2^30)-240*(10^9))/(240*(10^9)) = 14.5%

除了滿足基本的使用要求外,OP變大有什麼壞處或者好處呢?壞處很顯然,使用者能使用的SSD容量變小。那麼好處呢?

回到垃圾回收原理來。

再看一下這張圖。回收Block x,上面有3個有效Page,需要讀寫3個Page完成整個Block的回收;而回收Block y時,則需要讀寫4個有效Page。兩者相比,顯然回收Block x比回收Block y快一些。說明一個簡單的道理:一個Block上有效的資料越少(垃圾資料越多),則回收速度越快。

256GB FLASH配成256GB的SSD (OP = 7.37%), 意味著256*(10^9)的有效資料寫到 256*(2^30)的空間,每個Block上面的平均有效資料率可以認為是256*(10^9)/256*(2^30) = 93.1%。

如果配成240GB的SSD,則意味著240*(10^9)的有效資料寫到256*(2^30)的空間,每個Block的平均有效資料率為240*(10^9)/256*(2^30) = 87.3%。

OP越大,每個Block平均有效資料率越小,因此我們可以得出的結論:OP越大,垃圾回收越快,寫放大越小。這就是OP大的好處。

寫放大越小,意味著寫入同樣多的HOST資料,寫入到FLASH中的資料越少,也就意味著FLASH損耗越小。FLASH都是有一定壽命的,它是用P/E數 (Program/Erase Count)來衡量的。(關於FLASH基礎知識,請參考《快閃記憶體基礎》)。如果SSD集中對某幾個Block進行擦寫,那麼這幾個Block很快就壽命耗盡。比如在使用者空間,有些資料是頻繁需要更新的,那麼這些資料所在Block就需要頻繁的進行擦寫,這些Block的壽命就可能很快的耗盡。相反,有些資料使用者是很少更新的,比如一些只讀檔案,那麼這些資料所在的Block擦寫的次數就很少。隨著使用者對SSD的使用,就會形成一些Block有很高的PE數,而有些Block的PE數卻很低的。這不是我們想看到的,我們希望所有Block的PE數都應該差不多,就是這些Block被均衡的使用。在SSD內部,有一種叫磨損平衡(Wear Leveling,WL)的機制來保證這點。

WL有兩種演算法:動態WL和靜態WL。所謂動態WL,就是在使用Block進行擦寫操作的時候,優先挑選PE 數低的;所謂靜態WL,就是把長期沒有修改的老資料(如前面提到的只讀檔案資料)從PE數低的Block當中搬出來,然後找個PE 數高的Block進行存放,這樣,之前低PE數的Block就能拿出來使用。

可見,使不使用WL,以及使用何種WL演算法,對SSD的壽命影響是很大的。

小結:本文介紹了SSD的一些基本原理,包括SSD底層FLASH陣列的實現,Host Page與Physical Page的對映及對映表,垃圾回收機制,寫放大,OP和Wear Leveling等。雖然市面上有各種各樣的SSD,但它們內部這些基本的東西都是相通的。理解了這些東西,就等於擁有了一把通向SSD世界的鑰匙。