設計 SSD(固態硬盤)友好的程序

前言

為了提升我們的軟件性能,我們有多種方法,如合理的數據結構、優秀的算法,還有非常重要的一點就是:依據軟件所依附的硬件自身特性,設計能最大限度發揮硬件性能的軟件。根據計算機內存快但無法持久化,硬盤可以持久化但是慢的特性,我們設計了「緩存」這一策略來提升性能;根據硬盤隨機讀寫慢但順序讀寫快這一特性,Kafka 用自己獨特的方式來實現高吞吐量的隊列。如今,由于 SSD 出色的性能以及逐漸降低的價格,有逐步代替 HDD(傳統硬盤)的趨勢,而我們之前的大部分程序是基于 HDD 開發的,并不能最好的發揮 SSD 的性能,因此,我們有必要了解 SSD 的特性,以及如何寫更適合于 SSD 的程序。

SSD 介紹

SSD 是用固態電子存儲芯片陣列而制成的硬盤,由控制單元和存儲單元(FLASH芯片、DRAM芯片)組成。SSD 的每個數據位保存在由浮柵晶體管制成的閃存單元里。SSD整個都是由電子組件制成的,沒有像硬盤那樣的移動或者機械的部分。SSD 的內部架構如下:


SSD 內部架構

1. 使用壽命

SSD 的數據保存在浮柵晶體管中,浮柵晶體管使用電壓來實現每個位的讀寫和擦除。寫晶體管有兩個方法:NOR 閃存和 NAND 閃存。目前大多數制造商都采用 NAND 閃存,NAND 閃存模塊的一個重要特征是,他們的閃存單元是損耗性的,因此它們有一個壽命。衡量壽命的單位是 PE周期(program/erase cycles)

2. 性能

下圖是 SSD 與其他存儲介質的性能對比:

SSD 與其他存儲介質的性能對比

其中 SLC、MLC、TLC 可以理解為不同類型的 SSD,下面會有介紹。

2. 存儲結構

SSD 存儲結構分為單元、頁、塊三層,下面依次介紹:

  • 單元(cell):單元是 SSD 存儲的最小單位,由于采用的閃存類型不同,各類閃存中的單元能存儲的數據也不同,目前有三種閃存單元類型:

    • 單層單元(SLC),這種的晶體管只能存儲 1 個比特但壽命很長。
    • 多層單元(MLC),這種的晶體管可以存儲 2 個比特,但是會導致增 加延遲時間和相對于SLC減少壽命。
    • 三層單元(TLC),這種的晶體管可以保存 3 個比特,但是會有更高的延遲時間和更短的壽命。
  • 頁(page):頁由許多單元組成,是我們讀寫 SSD 的最小單位,大多數硬盤的頁大小是 2KB、4KB、8 KB 或 16 KB。當我們讀 SSD 的數據時,最少讀取一頁(就算我們只需要 1 字節的數據);當我們寫數據時,就算只需要寫 1 字節,也會寫一頁,因此存在寫入放大的問題。頁不能被重復寫。

  • 塊(block):塊由許多頁組成,是數據擦除的最小單元,大多數SSD每個塊有128或256個頁。這即表示一個塊的大小可能在 256 KB 到 4 MB 之間。之前我們說過,頁不能被重復寫,要修改頁的數據,必須先將頁所在的塊擦除,然后再重新寫入新值(塊中其他葉需要緩存然后再寫入)。

3. 數據更新

由于 SSD 不支持數據覆蓋寫入,因此對于數據的更新,只能將老的數據標記為過期,在另外一個空閑的地方寫入更新后的值。具體操作如下圖:


數據更新過程

由上圖我們可知,更新一個已有數據的流程如下:

  1. 將老的數據所在的頁(PPN=0)標記為過期
  2. 在空閑頁(PPN=3)寫入新值 x'
  3. 當垃圾回收程序檢測到該塊(Block 1000)中存在過期數據(PPN=0),準備將其回收。而數據的擦除是以塊為單位的,因此,需要先將 Block 1000 中有效的數據拷貝到另外一個空閑塊(Block 2000),然后再將 Block 1000 擦除。

4. 損耗均衡

由于 SSD 存儲單元的擦除次數是有限的,而擦除的最小單位是塊,所以需要有一個機制來平衡各塊的擦除次數,從而使整個 SSD 的各部分損耗更加均衡,這一機制稱為損耗均衡。通過該技術,存儲數據會在不同的塊之間移動,以避免對同一塊的頻繁擦除。

5. 內部并行

因為物理限制的存在,異步 NAND 閃存 I/O 總線無法提供32-40 MB/s以上的帶寬。由于一塊 SSD 是由多個存儲芯片組成的,因此我們可以通過并行讀寫多個存儲芯片的方式來提升 SSD I/O 的性能。

SSD 內部將不同芯片中的多個塊稱為一個簇(clustered block),一次數據寫入可以并行的寫入到簇中的不同塊中。如下圖中,一次數據寫入可以拆封成多個并行寫入的任務,寫入到黃色虛線框的簇中。

clustered block 并行寫入

6. 垃圾回收

上面我們已經講到,SSD 中的數據是不能被重復寫的,必須先擦除然后再寫,而擦除的速度非常慢(通常為毫秒級),SSD控制芯片會執行垃圾回收操作,即回收使用過的塊,確保后續寫操作能夠快速分配到可用的塊。

設計 SSD 友好的程序

針對上述介紹的 SSD 特性,在開發程序時我們可以做一些針對性的設計,以提高 SSD 的性能,還有延長 SSD 的使用壽命。

1. 對齊寫入

SSD 數據寫入的最小單元是頁,因此,如果我們寫入的數據小于頁大小,會有兩個危害:

  • 空間浪費:如果想再次利用頁中的空閑部分,必須擦除所處的整個塊
  • 讀取效率低:一次讀取讀到的有效數據少,讀相同數據需要更多次讀操作

對齊寫入指一次數據寫入是頁大小的整數倍,如果數據不夠足,可以先緩沖在內存中,例如 Twitter 的 fatcache 就是湊夠了1MB 才會寫 SSD。

2. 相關的數據一起寫

相關的數據一起寫指的是對于經常被一起訪問的數據,寫的時候盡量一次同時寫入,這樣做有兩個層面的好處:

  • 由于讀寫的最小單位是頁,相關的數據寫在一頁上,數據讀的時候效率高
  • 由于 SSD 存在內部并行的特性,一次將大量(簇大小的整數倍)相關的數據同時寫入,內部會優化并行寫入到各個存儲芯片,讀的時候也能并行讀取,可以提升讀的性能
3. 將冷熱數據分開寫

將冷熱數據分開寫主要是防止由于冷熱數據范圍頻率不同而導致的寫入放大,如果將冷熱數據寫一起,將會有兩個層面的缺點:

  • 如果冷熱數據在同一個頁上:數據塊小于16KB或不對齊16KB時,更新熱數據不得不讀改寫冷數據。
  • 如果冷熱數據在同一個塊上:垃圾回收熱數據時,不得不搬移并重寫冷數據。
4. 緩存熱數據

我們知道 SSD 對于數據更新,只能通過擦除-寫入的方式,對于非常高頻變化的數據,要對數據所在塊進行頻繁的擦除-寫入,對整體性能會有較大影響。所以建議對熱數據進行程序的緩存,而不是寫入磁盤。

5. 讀寫分離

混合的小讀寫交叉的工作負載會妨礙內部緩存和預讀取機制正常工作,并會導致吞吐量下降。最好的辦法是避免同時發生的讀操作和寫操作,并將其以一個接一個的大數據塊的形式實現,數據塊大小推薦和簇大小相同。舉個例子,如果要更新1000個文件,你可以遍歷文件逐一讀寫,但會很慢。如果一次讀取1000個文件然后一次寫回1000個文件將會好很多。

6. 避免長時間大數據寫入

SSD 內部存在異步垃圾回收進程,一般情況下不會影響正常的 I/O,但是如果長時間大數據寫入,可能存在垃圾回收速度跟不上寫入速度的情況,導致寫入請求需要等待垃圾回收進程擦除塊,影響性能。

7. 避免就地(in-place)更新優化

由于HDD在查找數據時又尋道時間,為了避免尋道產生的延遲,應用程序常常被優化成就地更新。但這個優化對于 SSD 并不適用,因為 SSD 沒有尋道時間,且不支持覆蓋寫,更新數據必須先擦除,再寫入,所以就地更新反而會造成性能下降,下圖是 SSD 與 HDD 就地更新的性能對比:


HDD 和 SSD 隨機更新和就地更新 qps
8. 對于大的(大于簇的大?。┳x寫操作,單線程比多線程好

造成這個現象的原因就是我們上面說到過的 SSD 存在內部并行的機制。

  • 對于大的寫入,由于內部并行機制的存在,單線程也能達到多線程的性能,并且,一個大的單線程寫入比并發寫入延遲時間更短。因此,在可用的時候,使用單線程大寫入是最好的。
  • 對于大的讀取,單線程讀不僅可以依靠內部并行機制達到多線程讀同樣的性能,而且可以更好的使用預讀取機制,因此比多線程并發讀更優。
9. 對于小數據的讀寫,多線程比單線程好

如果數據太小且沒辦法進行合并后讀寫,就無法使用其內部并行機制,因此多線程更優。

總結

本文分析了一些 SSD 的特性,以及針對這些特性,我們應該如何設計更適合于 SSD 的程序。SSD 是提升磁盤性能的利器,目前看也大有替代傳統 HDD 的趨勢,因此建議廣大工程師都對其有所了解。當然,SSD 目前也在快速的發展之中,可能有些特性會隨著發展而改變,希望大家能及時同步最新知識。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容

  • 簡介 SSD(Solid State Drives),俗稱固態硬盤,相對原來主軸旋轉,并無機械部分,主要由SS...
    mysia閱讀 5,048評論 0 10
  • MySQL技術內幕:InnoDB存儲引擎(第2版) 姜承堯 第1章 MySQL體系結構和存儲引擎 >> 在上述例子...
    沉默劍士閱讀 7,447評論 0 16
  • 今天是我的20歲生日,雖然過得并沒什么特別,但是還是覺得這是我生命中一個非常重要的時刻,想要記錄下此刻的心情。 想...
    苔花小姐閱讀 212評論 1 0
  • 1. 雯雯部門最近碰到一個事,不大,但后果比較嚴重。 2. 一開始,雯雯心里也很不好受,雖然不是自己直接造成的,但...
    文曉玲閱讀 1,520評論 12 10
  • 無論人生哪一個階段,都必須要努力,不能停歇。不然跟不上大家進步的步伐。
    站在十字路口閱讀 197評論 0 0