SSD Steady-State Behavior
YouTube 開箱影片裡,評測者拿到一顆全新的 NVMe SSD,打開 CrystalDiskMark,跑出 sequential read 7,000 MB/s 的成績,彈幕一片「好猛」。但如果你把同一顆 SSD 拿來當 OS 碟用了半年,每天承受系統 log、瀏覽器 cache、各種應用程式的零碎寫入,再跑一次同樣的 benchmark,數字會不太一樣。差距不是因為 SSD 壞了,而是因為第一次測的是 fresh state,第二次面對的是 steady state,這是兩個完全不同的運作條件。只看開箱成績就下單的 SSD 評測,跟只看入學成績不看畢業率的大學排名一樣,只說了故事的前半段。
Fresh state vs steady state
Fresh state 的特徵:
- NAND flash 上所有 block 都是 erased 的(空白的)
- 每次寫入都直接找一個空白 page,零 GC 開銷
- Write amplification 接近 1(幾乎沒有額外寫入)
- 寫入延遲非常穩定,幾乎看不到 tail latency spike
Steady state 的特徵:
- NAND flash 上大部分 block 都已經被寫過
- 每次寫入都可能觸發 GC 來回收空間
- WAF 明顯大於 1(典型值 2-5,取決於 workload 和 OP)
- 寫入延遲出現顯著的 tail latency spike(p99 延遲可能是 p50 的 10-100 倍)
從 fresh state 過渡到 steady state 的過程很簡單:持續寫入資料,直到 SSD 第一次耗盡所有空白 block、開始觸發 GC。對於消費級 SSD(7% OP),這大約是寫滿 SSD 容量一次之後就會開始進入 steady state。對於企業級 SSD(28% OP),可能需要寫滿 1-2 次。
一個常被忽略的事實是:steady state 的效能可能只有 fresh state 的 30-50%。也就是說,規格表上 500K IOPS 的 SSD,在 steady state 下可能只剩 150-250K IOPS。這不是 SSD 壞了,這是正常行為。
GC 與 user I/O 的頻寬競爭
為什麼 steady state 的效能會下降?根本原因是 GC 和使用者的 I/O 請求在競爭 NAND flash 的頻寬。
NAND flash 的 die/plane 在任何時刻只能做一件事:要嘛服務使用者的讀寫請求,要嘛執行 GC 的資料搬移和 block erase。當 GC 正在搬移 valid page 時,使用者的寫入請求必須等待(或者被路由到其他 die,如果有空閒的話)。
這個競爭造成了兩種效能影響:
平均 throughput 下降:假設 NAND flash 的總頻寬是 2 GB/s。如果 GC 需要消耗其中 40% 的頻寬來搬移 valid page 和做 block erase,那使用者實際可用的頻寬只剩 1.2 GB/s。WAF 越高,GC 消耗的頻寬比例越大,使用者可用的頻寬越少。
Tail latency spike:更大的問題不是平均值下降,而是延遲的「不可預測性」。GC 操作是 bursty 的:有時候 SSD 有足夠的 free block,GC 不需要工作,延遲很低;有時候 free block 快耗盡,GC 緊急介入,一口氣要搬移大量資料,期間使用者的 I/O 全部被阻塞。
在一些對延遲敏感的應用場景(例如資料庫的 transaction processing),p99 latency 比 average latency 更重要。一個平均延遲 0.1 ms 但 p99 延遲 50 ms 的 SSD,在這些場景下可能不如一個平均延遲 0.2 ms 但 p99 延遲 2 ms 的 SSD。
SSD 韌體可以用一些策略來緩解 tail latency:
- Background GC:在 SSD idle 的時候主動做 GC,預先回收空間。但如果 workload 持續不停,idle 時間很少,background GC 幫助有限。
- GC pacing:限制 GC 的頻寬佔比,避免 GC 一次性佔用太多資源。但這可能導致 free block 耗盡的情況更容易發生。
- Multi-stream write:讓 host 端告知 SSD 資料的冷熱屬性,SSD 把冷熱資料分開放在不同 block 中,提高 GC 效率。
Over-provisioning 與 steady state 效能
Over-provisioning(OP)比例是影響 steady state 效能最直接的因素。
用一組具體數字來說明。假設一顆 SSD 有 1,024 GB 的 NAND flash:
| 標示容量 | OP 比例 | OP 空間 | Steady state WAF | Steady state throughput(相對) |
|---|---|---|---|---|
| 960 GB | 7% | 64 GB | ~3-5 | 低 |
| 800 GB | 28% | 224 GB | ~1.5-2 | 中 |
| 640 GB | 60% | 384 GB | ~1.1-1.3 | 高 |
OP 比例從 7% 提高到 28%,WAF 可以降低一半以上,steady state throughput 明顯提升。但代價是使用者可用容量從 960 GB 減少到 800 GB。
為什麼 OP 能這麼有效?因為更多的 OP 代表:
- 任何時刻都有更多 free block 可用,GC 不需要在空間緊迫時才啟動
- GC 有更多選擇,可以挑選 invalid page 比例高的 block 來回收,搬移的 valid page 更少
- GC 的啟動頻率更低,與 user I/O 的競爭更少
這也解釋了為什麼企業級 SSD 通常提供多種容量版本(例如 800 GB、1.6 TB、3.2 TB)但使用相同的 NAND flash 總量。800 GB 版本有更多 OP,效能和壽命都更好,適合 write-intensive workload;3.2 TB 版本 OP 較少,適合 read-intensive workload。
正確的 SSD benchmarking methodology
理解了 fresh state 和 steady state 的差異後,最重要的實務意義就是:SSD 的效能測試必須在 steady state 下進行,否則結果沒有參考價值。
正確的 benchmarking 流程(參考 SNIA 的 Solid State Storage Performance Test Specification, SSSI PTS):
Step 1: Preconditioning(預處理)
在正式測量前,先用與實際 workload 類似的 I/O pattern 對 SSD 進行持續寫入,直到效能指標穩定下來。「穩定」的判斷標準通常是:連續多個測量週期(例如每個週期 1 分鐘)的 throughput 或 IOPS 變異係數(coefficient of variation)低於某個閾值(例如 10%)。
對於 random write 測試,preconditioning 通常需要:
- 先用 sequential write 填滿整顆 SSD 兩次(確保所有 block 都被寫過)
- 再用目標 random write pattern 持續寫入,直到效能穩定
整個 preconditioning 可能需要數小時甚至一天。
Step 2: Steady-state measurement(穩態測量)
Preconditioning 完成後,開始正式的效能測量。測量時間要足夠長,覆蓋多個 GC cycle,才能準確反映 GC 對效能的影響。通常建議至少測量 30 分鐘到 1 小時。
Step 3: 記錄完整的延遲分佈
只報告 average throughput 或 average latency 是不夠的。必須記錄完整的延遲分佈,包括 p50、p90、p95、p99、p99.9、p99.99 甚至 max latency。因為 GC 造成的 tail latency spike 只會出現在高百分位數,average 值會完全掩蓋這個問題。
很多 SSD review 網站和廠商的規格表只報告 fresh state 下的數字。下次你看到論壇上有人說「我這顆 SSD 跑分比你快」,先問一個問題:他測的是剛開箱的成績,還是用了三個月之後的成績?身為系統設計者,你需要知道這些數字在 steady state 下可能縮水 50% 以上。如果你在設計一個 latency-sensitive 的系統,你必須用 steady state 下的 p99 甚至 p99.9 latency 來做 capacity planning,而不是用 fresh state 的 average latency。
自問自答
-
一顆消費級 SSD(7% OP)和一顆企業級 SSD(28% OP)使用相同的 NAND flash。在 fresh state 下它們的 sequential write 效能幾乎相同。為什麼在 steady state 下企業級 SSD 的效能明顯優於消費級?
-
為什麼只看 average latency 不足以評估 SSD 在生產環境的表現?請用一個具體的應用場景(例如 OLTP 資料庫)說明 tail latency spike 會造成什麼實際問題。
-
描述一個完整的 SSD steady-state benchmarking 流程。為什麼 preconditioning 階段需要先 sequential write 填滿 SSD 再切換到目標 workload pattern?
-
一顆 SSD 在 fresh state 下的 random write IOPS 是 400K,steady state 下降到 150K。請推算 GC 大約消耗了多少比例的 NAND flash 頻寬。
-
如果你要設計一個 write-intensive 的 key-value store 系統,在選擇 SSD 時你會優先考慮哪些 steady-state 相關的指標?為什麼 OP 比例可能比標示容量更值得關注?