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)。

  HOST寫入4KB數據

 


  HOST繼續寫入16KB數據

 


  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 Application)並在公開稿件里用到這個術語。

 


  在上面例子中,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*^9)/(256*^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和靜態WL下的FLASH耐久度的區別 (假設每個Block最大PE數為10,000):(圖片來自http://www.pceva.com.cn/topic/crucialssd/images/6/006.jpg)

 


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

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

 

轉自:http://www.360doc.com/content/17/0411/11/41875488_644636812.shtml


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM