為SSD程式設計(4):高階功能和內部並行

熊鐸發表於2014-05-10

在這個部分,我將簡要的介紹固態硬碟(SSD)的一些主要功能,如TRIM和預留空間。還會介紹SSD中不同等級的內部並行。

5. 高階功能

5.1 TRIM 

讓我們假設一個程式向SSD所有的邏輯塊地址都寫入檔案,這個SSD當然會被裝滿。然後刪除這些檔案。檔案系統會報告所有的地方都是空的,儘管硬碟實際上還是滿的,因為SSD主控沒法知道邏輯資料是什麼時候被主機刪掉的。SSD主控只會在這些邏輯塊地址被複寫的時候才知道這些是空閒空間。此時,垃圾回收程式將會擦除與這些檔案相關的塊,為進來的寫操作提供空的頁。其結果就是,擦除操作並非在知道儲存有無用資料之後立刻執行,而是被延遲了,這將嚴重影響效能。

另一個值得關心的是,既然SDD主控不知道這些頁儲存有已刪除的檔案,垃圾回收機制仍然會為了損耗均衡而移動這些頁上的資料。這增加了寫入放大,並毫無意義地影響了來自主機的前臺工作負載。

延遲擦除問題的一個解決方法是TRIM命令,這個命令由作業系統傳送,通知SSD控制器邏輯空間中的這些頁不會再使用了。有了這個資訊,垃圾回收程式就會知道自己不必再移動這些頁,並可以在任何需要的時間擦除它們。TRIM命令只會在當SSD、作業系統和檔案系統都支援的時候才起作用。

TRIM命令的維基百科頁面列出了支援TRIM的作業系統和檔案系統[16]。Linux下,ATA TRIM的支援是在2.6.33版本加入的。儘管ext2和ext3 檔案系統不支援TRIM,ext4 和XFS以及其他的一些是支援的。在Mac OS 10.6.8下,HFS+支援TRIM操作。Windows 7則只支援使用SATA介面的SSD的TRIM,使用PCI-Express的則不支援。

現在大部分的硬碟都支援TRIM,確實,允許垃圾回收儘早的工作顯著地提升了將來的效能。因此強烈建議使用支援TRIM的SSD,並確保作業系統和檔案系統級都啟用了TRIM功能。

 

5.2 預留空間

預留空間只是簡單的使物理塊比邏輯塊多,即為主控保留一定比例的,使用者不可見的物理塊。大多專業級SSD生產商已經包括了一些預留空間,通常是7~25%[13]。使用者可以簡單的通過建立比最大物理容量小的邏輯容量分割槽來建立更多的預留空間。例如,你可以在100G的硬碟上建立一個90G的分割槽,而把剩下的10G作為預留空間。即使預留空間在作業系統級是不可見的,但SSD主控仍然是可以看見的。生產商提供預留空間的主要原因是為了對付NAND快閃記憶體單元固有的獸獸門限制。不可見的預留空間的塊將無縫的替換可見空間上的已耗損殆盡的塊。

AnandTech有一篇有意思的文章顯示出預留空間對SSD壽命和效能的影響[34]。在他們研究的硬碟上,結果顯示出僅通過保證25%的預留空間(把所有的預留空間加在一起)就可以使效能極大地提升。在Percona的一篇文章中有另外一個有意思的結果,在他們測試了一塊Intel 320 SSD,顯示出當硬碟逐漸填滿時,寫入吞吐量將隨之下降[38]

這裡是我的實驗中發生的事情。垃圾回收是使用空閒時間在後臺擦除頁上不再使用的資料的。但既然擦除操作比寫入操作的延遲更久,或者說擦除要的時間比寫入長,在持續的重隨機寫入工作負載下的SSD將會在垃圾回收有機會擦除之前用盡所有的空塊。此時,FTL將不能跟上前臺的隨機寫入工作負載,而垃圾回收程式將必須在寫入命令進來的同時擦除塊。這就是在基準測試中SSD效能下降的厲害,而SSD顯得效能超差的時候,如下圖7所示。因此,預留空間可以吸收高吞吐量寫入負載,起到緩衝的作用,為垃圾回收跟上寫入操作並重新開始擦除無用塊留夠時間。預留空間需要多少大部分基於SSD使用環境的工作負載,和其需要的承受的寫入操作的量。作為參考,持續隨機寫入的工作負載比較推薦使用大約25%的預留空間[34]。如果工作負載不是很重,大概10~15%估計夠大的了。

預留空間對損耗均衡和效能表現是有用的

SSD可以簡單地通過格式化時設定比最大物理容量小的邏輯容量來啟動預留空間。餘下的不被使用者所見的空間仍會被SSD主控所用。預留空間幫助損耗均衡機制來對付NAND快閃記憶體單元的壽命限制。對於寫入不是很重的工作負載,10~15%的預留空間足夠了。對於持續的隨機寫入工作負載,保持25%的預留空間將會提升效能。預留空間將會扮演NAND快閃記憶體塊的緩衝區的角色,幫助垃圾回收程式吸收寫入峰值。

從此,同樣可以推匯出,預留空間甚至可能為不支援TRIM命令的環境提供更大的效能提升——注意我只是在這進行個假設,我仍然在尋找材料來支援這個觀點。假設只有75%的硬碟空間可被作業系統使用,餘下的25%留作預留空間。因為SSD控制器可以看見整個硬碟,儘管在某一時刻只有75%的物理NAND快閃記憶體被使用,但100%的塊都在已使用、已廢棄、已擦除三種狀態中交替轉換。這表示餘下的25%物理快閃記憶體將可以安全的認為沒有儲存有資料,因為其並沒有被對映到任何邏輯塊地址上。因此,即使不支援TRIM,垃圾回收程式也能夠提前擦除這些預留空間中塊。

5.3 安全擦除

一些SSD主控提供ATA安全擦除功能,其作用是當硬碟處於意料之外的狀態時恢復其效能。這個命令擦除所有使用者寫入的資料並重置FTL對映表,但這顯然不能克服P/E迴圈有限造成的物理限制。儘管其功能上看上去非常有前途,但需要每個生產商爭取的實現它。Wei等人2011年在他們關於安全擦除命令的review中顯示,在他們研究的超過12個型號SSD中,只有8個提供了ATA安全擦除功能,而在這8個硬碟中,三個都有各種bug[11]

對於效能的影響是很重要的,並且在安全方面更加重要,但我不想展開說。這裡有幾個Stack Overflow上的討論可以解釋關於如何可靠地刪除SSD中的資料的細節。

5.4 原生命令佇列(NCQ)

原生命令佇列(NCQ)是SA他的一個功能,其允許SSD接受來自主機的多個命令,使SSD可以使用內部並行同時完成這些命令[3]。除了減少因為硬碟造成的延遲外,一些新的硬碟同樣使用NCQ來應對來自主機的延遲。例如NCQ可以優先傳入的命令來確保當主機CPU忙的時候硬碟總是有命令處理。

5.5 斷電保護

無論是在家還是在資料中心,斷電都是有可能發生的。一些生產商在他們的SSD結構中設定有超級電容,這個電容設計為存有足夠提交匯流排中所有I/O請求所需的能量以防掉電。問題在於並非所有的SSD生產商都為他們的硬碟設定超級電容或者某種掉電保護,而有超級電容的不總是在說明書中提及。然後,和安全擦除命令一樣,斷電保護機制的實現是否正確,並且是否確實能夠在掉電時避免資料損壞是搞不清楚的。

Zheng等人2013年的研究中測試了15個SSD,但沒有透露品牌[72]。他們給硬碟各種各樣的電源故障,發現測試的15個SSD中有13個最終丟失資料或者大規模的資料損壞。在另外一篇Luke Kenneth Casson Leighton寫的關於電源故障的文章中顯示出,測試的4個硬碟有3個最終都在不正確的狀態,剩下的一個沒有問題(是Intel的硬碟)[73]

SSD還是一個非常年輕的技術,並且我相信這些電源故障下造成資料損壞的阻力將會在接下來的產品中克服。然而現在,在資料中心配置不間斷電源(UPS)可能還是應該做的。並且和任何其他儲存解決方案一樣,經常備份敏感資料。

6.SSD中的內部並行

6.1 匯流排頻寬限制

因為物理限制的存在,非同步NAND快閃記憶體I/O匯流排無法提供32-40 MB/s以上的頻寬[5]。SSD生產商提升效能的唯一辦法是以某種方法讓他們的硬碟中的多個儲存晶片可以並行或者交錯。[2]的2.2節中有一個比較好的關於交錯的解釋。

通過組合SSD內所有層次的內部並行,不同晶片中的多個塊可以作為一個叫clustered block(直譯是叢集塊,但我感覺用比較親切,本譯文中所有的簇都是指它)東西同時訪問。我不打算解釋關於SSD內部並行的所有細節,因此我只簡述一下並行的層次和簇。獲取更多關於這個話題的資訊,以及SSD內部並行的概括,這裡的兩篇論文是很好的開始[2, 3]。此外,一些高階命令如copybackinter-plane transfer[5]中有闡述。

內部並行

在SSD內部,數個層次的並行允許一次將數個塊寫入到不同的NAND快閃記憶體晶片中,這些塊稱為簇。

6.2 並行的多級別

下邊的圖6展示了NAND快閃記憶體晶片的內部,其組織為一種分級的結構。這些級別包括通道、封裝、晶片、面、塊和頁。如[3]中揭示的,這些不同的層通過下邊的方法提供並行

  • 通道級並行 快閃記憶體主控和快閃記憶體封裝之間的通訊通過數個通道。這些通道可以獨立或者同時訪問。每個獨立通道有數個封裝共享。
  • 封裝級並行 一個通道中的不同封裝可以獨立訪問。交錯可以使命令同時在同一個通道中的不同封裝中執行。
  • 晶片級並行 一個封裝包含兩個或者更多的晶片,晶片可以並行獨立訪問。注:晶片通常也被稱為核心(chips are also called “dies”)
  • 面級並行 一個晶片包含兩個或者更多的面。相同的操作(讀、寫或者擦除)可以在晶片中多個面上同時執行。麵包含了塊,塊包含了頁。面也包含了暫存器(小RAM快取),其用在面級操作上。

圖6: NAND 快閃記憶體封裝

6.3 簇

譯註: 本節標題原文是“clustered blocks”,詞典上沒有這個詞(片語?),Google了也沒有發現合適的翻譯,其直譯是“叢集的塊”或者“成簇的塊”。因為這個“clustered blocks”和“簇”的英文“Data cluster”比較像,特性上也相似(都是若干儲存單位的集合),決定將這個“clustered blocks”在本文中譯為“簇”。但這個簇與機械硬碟的簇不是相同的東西,請讀者注意分辨。如果有更為合適或者正規的翻譯請告訴我。

從多個晶片中訪問到的多個塊被稱為一個[2]。這個做法比較像RAID系統中的striping[1, 5]

一次訪問的邏輯塊地址被分到不同SSD快閃記憶體封裝中的不同晶片上。這歸功於FTL的對映演算法,並且這與這些地址是否連續無關。分割塊允許同時使用多個通道來整合其頻寬,並同樣可以並行執行多個讀、寫和擦除操作。這即表示I/O操作按簇大小對齊來確保SSD中多個級別的內部並行所提供的效能能夠最大程度的利用。

 

相關文章