基本操做:緩存
讀出、寫入、擦除:數據結構
由於NAND閃存單元的組織結構限制,單獨讀寫一個閃存單元是不可能的。存儲單元被組織起來並有着十分特別的屬性。要知道這些屬性對於爲固態硬盤優化數據結構的過程和理解其行爲來講是很重要的。我 在下方描述了關於讀寫擦除操做的SSD的基本屬性性能
讀是以頁大小對齊的優化
一次讀取少於一頁的內容是不可能的。操做系統固然能夠只請求一字節,可是SSD會訪問整個頁,強制讀取遠超所需的數據。操作系統
寫是以頁大小對齊的code
將數據寫入SSD的時候,寫入的增量也是頁大小。所以即便一個寫入操做隻影響到一個字節,不管如何整個頁都會寫入。寫入比所需更多的數據的行爲被稱爲寫入放大,其概念在3.3節。另外,向某頁寫入的行爲有時候被稱爲「編置(to program)」一頁,所以在大多數關於SSD的出版物和文章中「write 寫」和「program編置」是能夠互相替換的blog
頁不能被複寫進程
NAND閃存頁只有在其「空閒」着的時候才能寫入。當數據改變後,這頁的內容被拷貝到一個內部寄存器,此時數據更新而新版本的數據存儲在一個「空閒」的頁中,這被稱爲「讀-改-寫」操做。數據並不是就地更新,由於「空閒」頁與原來存儲數據的頁不是同一個頁。一旦數據被硬盤保存,原先的頁被標記爲「stale(意爲 腐敗的 不新鮮的)」,直到其被擦除。get
擦除以塊對齊flash
頁不能被複寫,而一旦其成爲stale,讓其從新空閒下來的惟一方法是擦除他們。可是對單個頁進行擦除是不可能的,只能一次擦除整個塊。在用戶看來,訪問數據的時候只有讀和寫命令。擦除命令則是當SSD控制器須要回收stale頁來獲取空閒空間的時候,由其垃圾回收進程觸發。
寫入的例子:
下邊的圖是向SSD寫入的一個例子。只顯示了兩個塊,每一個塊有4個頁。顯然這是一個爲了簡化我在這使用的例子而精簡的NAND閃存封裝示意。圖中的每一步裏,圖右側的圓點解釋了發生的事情。
寫入放大:
由於寫入是按頁大小對齊的,任何沒有對齊一個或者多個頁大小的寫操做都會寫入大於所需的數據,這是寫入放大的概念[13]。寫一個字節最終致使一整頁都要寫入,而一頁的大小在某些型號的SSD中可能達到16KB,這是至關沒有效率的。
而這不是惟一的問題。除了寫入過多的數據外,這些額外的寫入也會觸發更多沒必要要的內部操做。實際上,用未對齊的方法寫入數據會致使在更改和寫回硬盤以前須要頁讀到緩存,這比直接寫入硬盤要慢。這個操做被稱爲讀-改-寫,且應該儘量的避免[2, 5]。
毫不進行少於一頁的寫入
避免寫入小於NAND閃存頁大小的數據塊來最小化寫入放大和讀-改-寫操做。如今一頁的大小最大的是16KB,所以這個值應做爲缺省值使用。閃存頁大小的值基於SSD型號而且在將來SSD發展中可能會增長。
對齊寫入
以頁大小對齊寫入,並寫入大小爲數個頁大小的數據塊。
緩存化小寫入
爲了最大化吞吐量,儘量的將小數據寫入RAM緩存中,當緩存滿了以後執行一個大的寫入來合併全部的小寫入。
損耗均衡
如咱們在1.1節討論的那樣,NAND閃存單元因其有P/E循環限制致使其有生命限制。想象一下咱們有一個SSD,數據老是在同一個塊上寫入。這個塊將很快達到其P/E循環限制、耗盡。而SSD控制器井標記其爲不可用。這樣硬盤的容量將減少。想象一下買了一個500GB的硬盤,過了幾年還剩250G,這會很是惱火。
所以,SSD控制器的一個主要目標是實現損耗均衡,便是將P/E循環在塊間儘量的平均分配。理想上,全部的塊會在同一時間達到P/E循環上限並耗盡。[12, 14]
爲了達到最好的全局損耗均衡,SSD控制器須要明智的選擇要寫入的塊,且可能須要在數個塊之間移動,其內部的進程會致使寫入放大的增長。所以,塊的管理是在最大化損耗均衡和最小話寫入放大之間的權衡。
製造商想出各類各樣的功能來實現損耗均衡,例以下一節要講的垃圾回收。
由於NAND閃存單元會耗盡,FTL的一個主要目標是儘量平均的將工做分配給各個閃存單元,這樣使得各個塊將會在同一時間達到他們的P/E循環限制而耗盡。
垃圾回收
頁不能被複寫。若是頁中的數據必須更新,新版本必須寫到空頁中,而保存以前版本數據的頁被標記爲stale。當塊被stale頁充滿後,其須要在可以再寫入以前進行擦除。
SSD控制器中的垃圾回收進程確保「stale」的頁被擦除並變爲「free」狀態,使得進來的寫入命令能夠訪問這個頁。
如第一節中所說,擦除命令須要1500-3500 μs,寫入命令須要250-1500 μs。由於擦除比寫入須要更高的延遲,額外的擦除步驟致使一個延遲使得寫入更慢。所以,一些控制器實現了後臺垃圾回收進程,或者被稱爲閒置垃圾回收,其充分利用空閒時間並常常在後臺運行以回收stale頁並確保未來的前臺操做具備不足夠的空頁來實現最高性能[1]。其餘的實現使用並行垃圾回收方法,其在來自主機的寫入操做的同時,以並行方式進行垃圾回收操做。
遇到寫入工做負載重到垃圾回收須要在主機來了命令以後實時運行的狀況並不是罕見。在這種狀況下,本應運行在後臺的垃圾回收進程可能會干預到前臺命令[1]。TRIM命令和預留空間是減小這種影響的很好的方法,具體細節將在6.1和6.2節介紹。
後臺操做可能影響前臺操做
諸如垃圾回收後臺操做可能會對來自主機的前臺操做形成負面影響,尤爲是在持續的小隨機寫入的工做負載下。
塊須要移動的一個不過重要的緣由是read disturb(讀取擾亂)。讀取可能改變臨近單元的狀態,所以須要再必定數量的讀取以後移動塊數據[14]。
數據改變率是一個很重要的影響因素。有些數據不多變化,稱爲冷數據或者靜態數據,而其餘一些數據更新的很頻繁,稱爲熱數據或者動態數據。若是一個頁一部分儲存冷數據,另外一部分儲存熱數據,這樣冷數據會隨着熱數據一塊兒在垃圾回收以損耗均衡的過程當中拷貝,冷數據的存在增長了寫入放大。這能夠經過將冷數據從熱數據之中分離出來,存儲到另外的頁中來避免。缺點是這樣會使保存冷數據的頁更少擦除,所以必須將保存冷數據和熱數據的塊常常交換以確保損耗均衡。
由於數據的熱度是在應用級肯定的,FTL無法知道一個頁中有多少冷數據和熱數據。改進SSD性能的一個辦法是儘量將冷熱數據分到不一樣的頁中,使垃圾回收的工做更簡單。
分開冷熱數據
熱數據是常常改變的數據,而冷數據是不常常改變的數據。若是一些熱數據和冷數據一塊兒保存到同一個頁中,冷數據會隨着熱數據的讀-改-寫操做一塊兒複製不少次,並在爲了損耗均衡進行垃圾回收過程當中一塊兒移動。儘量的將冷熱數據分到不一樣的頁中是垃圾回收的工做更簡單
緩存熱數據
極其熱的數據應該儘量多的緩存,並儘量的少的寫入到硬盤中。
以較大的量廢除舊數據
當一些數據再也不須要或者須要刪除的時候,最好等其它的數據一塊兒,在一個操做中廢除一大批數據。這會使垃圾回收進程一次處理更大的區域而最小化內部碎片。
reference: http://codecapsule.com/2014/02/12/