級SSD中的DRAM:從FTL命脈到掉電保護(hù)與容量挑戰(zhàn))
很多人第一次拆開企業(yè)級SSD看到主控旁邊整整齊齊排著好幾顆DRAM顆粒會下意識覺得這不就是個大號U盤嗎要那么多內(nèi)存干嘛。等真正做完一輪掉電實驗或者被線上一次盤卡死搞得焦頭爛額之后才會意識到這個問題的分量DRAM在公司級SSD里并不是錦上添花的緩存而是FTL閃存轉(zhuǎn)換層能正常運轉(zhuǎn)的命脈。這篇文章我想從一個做過存儲研發(fā)和運維的角度把DRAM在SSD里到底做什么、為什么企業(yè)級產(chǎn)品離不開它、以及它現(xiàn)在正在被哪些因素倒逼著改變盡量講清楚。不管你是剛?cè)胄械腟SD固件工程師、做存儲選型的架構(gòu)師還是單純對為什么有的SSD便宜有的SSD貴感到好奇的愛好者這篇文章都能讓你明白一件事企業(yè)級SSD的穩(wěn)定性和壽命很大程度是一顆顆DRAM顆粒和一套復(fù)雜的掉電保護(hù)機(jī)制換來的。1. 一塊企業(yè)級SSD里DRAM到底在干什么活1.1 不只是緩存DRAM承載的核心任務(wù)先說個最容易產(chǎn)生的誤解DRAM不是用來緩存用戶要讀取的數(shù)據(jù)那么簡單。它的真實身份更接近FTL的辦公桌。SSD底層是NAND閃存它有幾個和硬盤完全不同的脾氣不能覆蓋寫、寫之前必須先擦除、擦除以塊為單位而且每個物理塊能承受的擦寫次數(shù)有限。為了讓操作系統(tǒng)繼續(xù)用邏輯扇區(qū)號訪問數(shù)據(jù)主控必須維護(hù)一張邏輯地址到物理地址的映射表。這張表就是FTL的靈魂。主控每處理一次IO都要先查這張表把邏輯地址換算成NAND物理地址才知道數(shù)據(jù)該往哪兒放、該從哪兒讀。你把這張映射表放在哪里如果直接放NAND那每次讀操作都要先把映射表從NAND里讀出來NAND讀一次百來微秒再加一次用戶數(shù)據(jù)的讀取整個IO的延遲直接沒法看。所以必須把映射表的關(guān)鍵部分放在DRAM里讓主控以納秒級速度訪問。DRAM在這里扮演的是工作臺的角色映射表放桌面壞塊表貼墻上磨損均衡的狀態(tài)表放抽屜里正在寫的用戶數(shù)據(jù)在桌面上攤開等著聚合、排序湊滿一個NAND頁之后一次性刷下去。除了FTL元數(shù)據(jù)DRAM還承擔(dān)寫緩沖和寫聚合任務(wù)。舉個例子操作系統(tǒng)往SSD連續(xù)寫4KB小數(shù)據(jù)如果來一條寫一條NAND很痛苦每個16KB頁可能只寫了一小塊下次還得讀改寫。有了DRAM做聚合主控把多個零散寫請求拼成完整頁甚至完整塊再落盤寫放大系數(shù)能壓得比較低閃存的壽命和性能都會有保障。這就形成了第一個關(guān)鍵認(rèn)知DRAM之于SSD相當(dāng)于手術(shù)室之于外科醫(yī)生。你不能說手術(shù)刀很貴我只要一把刀就行了——場地和協(xié)同的設(shè)施才是手術(shù)能穩(wěn)定做下去的前提。SSD的DRAM省了FTL就得天天在NAND上做文章性能和壽命一定有個地方要還債。1.2 從一張映射表說起容量和命中率的真實賬本映射表到底占多大空間這塊可以做一道簡單的算術(shù)題。假設(shè)一塊1TB的企業(yè)級SSD映射粒度也就是一個映射條目覆蓋的邏輯空間大小是16KB。1TB邏輯空間除以16KB約等于6700萬個映射條目。每個條目要記錄物理頁地址、校驗信息、狀態(tài)標(biāo)志等等至少也要6到8個字節(jié)。乘下來大概400到600MB。如果把這套表用DRAM存起來再加上寫緩沖和元數(shù)據(jù)臨時區(qū)1TB的盤配1GB甚至2GB DRAM都是正常操作。這里有個非常核心的權(quán)衡映射粒度越小隨機(jī)讀性能越好、寫放大越小但DRAM占用越大映射粒度越大DRAM省了可是小隨機(jī)寫會頻繁觸發(fā)讀改寫寫放大直線上升。企業(yè)級主控一般會在16KB到64KB之間取平衡本質(zhì)上是在DRAM成本和寫放大之間做工程妥協(xié)。我經(jīng)常看到有人拿某消費級盤無DRAM來論證DRAM沒必要這個邏輯經(jīng)不起推敲。消費級無DRAM方案走的是HMBHost Memory Buffer路線。它利用主機(jī)PCIe協(xié)議提供的共享內(nèi)存區(qū)域把映射表的一部分放進(jìn)主機(jī)的DRAM里。好處是SSD本身不用帶DRAM成本大降壞處是這個共享內(nèi)存區(qū)域不是SSD獨占的主機(jī)CPU、其他應(yīng)用、其他盤都可能搶占它。這樣的方案在輕度負(fù)載的筆記本、普通桌面環(huán)境完全夠用但如果放到多租戶虛擬化、數(shù)據(jù)庫隨機(jī)寫重負(fù)載的環(huán)境里慘狀往往很可觀。提示區(qū)分一個SSD是不是真帶DRAM最直接的辦法是看拆解圖或者官方規(guī)格書里的DRAM一欄。無DRAM方案常常寫著HMB或DDR-less有PLP的企業(yè)級盤則會明確標(biāo)注Power Loss Protection和DRAM容量。2. 為什么消費級可以偷工減料企業(yè)級卻繞不開DRAM2.1 DRAM-less方案的生存邏輯DRAM-less方案不是低端的代名詞它在功耗和成本敏感的場景里有自己的位置。消費級SSD絕大多數(shù)場景是順序讀、低隊列深度、短突發(fā)寫入。比如開個軟件、加載個游戲、拷個文件單盤滿負(fù)荷的時間只占很小比例。這種模式HMB完全扛得住。主控通過PCIe把一小塊映射表緩存在主機(jī)內(nèi)存里每次映射表命中失敗再回NAND去加載表項一次IO可能多幾十微秒延遲但人眼感知不出來。消費級盤還有一個現(xiàn)實考量NAND顆粒價格已經(jīng)卷到很低一顆好的主控方案如果還要外掛DRAM整盤BOM成本增加可能超過20%零售價會難看。對廠商來說讓主控設(shè)計成DRAM-less利用HMB偷內(nèi)存是壓縮成本最直接的手段。2.2 企業(yè)級場景拒絕DRAM-less的三個硬道理企業(yè)級存儲環(huán)境要求的不是湊合能用而是任何時刻都能預(yù)測。DRAM-less在這里基本是禁區(qū)原因有三。第一性能可預(yù)測性。數(shù)據(jù)庫、OLTP這類負(fù)載的特點是隨機(jī)小寫密集隊列深度高Flash緩存又處于臟盤狀態(tài)。GC垃圾回收、磨損均衡、寫入聚合同時進(jìn)行時主控需要頻繁訪問映射表。如果映射表完全寄托在主機(jī)內(nèi)存里PCIe延遲和主機(jī)側(cè)資源競爭會成為新的不確定性來源。一旦主機(jī)內(nèi)存帶寬被虛擬機(jī)或網(wǎng)絡(luò)業(yè)務(wù)搶占SSD的P99.9延遲可能瞬間從幾毫秒飆到幾十毫秒。企業(yè)級客戶對這種尾延遲極其敏感SLA出問題就是事故。第二掉電安全。企業(yè)級SSD的DRAM方案通常和掉電保護(hù)強(qiáng)綁定。DRAM是易失的掉電瞬間數(shù)據(jù)可能沒落盤但主控借助電容放電可以把DRAM里的映射表臟頁和寫緩存強(qiáng)制刷回NAND。無DRAM方案雖然映射表也能存儲在NAND上但缺少大容量DRAM緩沖它要么頻繁刷盤增加NAND磨損要么在掉電時面對更多未完成寫入。把已確認(rèn)完成的寫入丟掉的損失在金融、醫(yī)療這類場景中是不可接受的。第三多租戶隔離和安全性。云平臺上一塊物理盤往往同時被多個虛擬機(jī)共享。HMB全局只有一個誰占用多誰就傷到別人更麻煩的是虛擬化場景下主機(jī)內(nèi)存的物理地址分布、搶占和回收都具有不確定性。一個有責(zé)任心的企業(yè)級主控固件不會愿意把自己的命脈懸在主機(jī)OS的內(nèi)存管理策略上。企業(yè)級方案要求的是盤內(nèi)自圓其說而不是看主機(jī)臉色。方案維度自帶DRAM企業(yè)級主流DRAM-less/HMB消費級常見映射表存放DRAM顆粒盤內(nèi)獨占借用主機(jī)內(nèi)存池區(qū)域訪問確定性高資源固定低受主機(jī)負(fù)載影響掉電保護(hù)可配PLP固件統(tǒng)一處理依賴HMB機(jī)制復(fù)雜度高典型場景數(shù)據(jù)庫、虛擬化、分布式存儲桌面辦公、輕量游戲、嵌入式3. 掉電那一瞬間DRAM里的數(shù)據(jù)如何搶救出來3.1 易失性帶來的連鎖問題DRAM最大的原罪就是斷電丟數(shù)據(jù)。一顆4KB扇區(qū)的寫請求進(jìn)來數(shù)據(jù)先落在DRAM寫緩沖里主控返回給主機(jī)寫完成。如果這時候突然掉電、而緩沖里的數(shù)據(jù)還沒來得及刷到NAND這塊數(shù)據(jù)就丟了。對用戶來說它的含義是系統(tǒng)告訴我寫成功了但數(shù)據(jù)沒了這比沒寫成功嚴(yán)重得多。更麻煩的是映射表。映射表里不光有用戶數(shù)據(jù)的地址還有尚未落盤的臟映射。如果臟映射跟著DRAM一起消失就算NAND里某些數(shù)據(jù)是完整的主控上電后也找不到它們整個邏輯卷都可能變成亂麻。所以企業(yè)級方案里掉電保護(hù)不是給DRAM裝個充電寶那么簡單而是一整套從硬件到固件的協(xié)同流程。3.2 從斷電瞬間到安全落盤PLP的完整鏈路下面我按順序拆解一次掉電事件里PLPPower Loss Protection是怎么運作的。電源監(jiān)測。主控和電源管理芯片時刻監(jiān)視各路供電電壓。當(dāng)檢測到電壓跌落到閾值以下主控會收到一個中斷信號PWR_FAIL標(biāo)志置位。這個信號從斷言到電壓真正降到主控?zé)o法工作中間通常有幾十毫秒的窗口。緊急凍結(jié)。主控收到掉電信號后第一件事是停止接收主機(jī)新命令NVMe隊列的新請求不再回復(fù)完成。已經(jīng)接收但還沒執(zhí)行的寫請求固件會盡量做完做不完的也不會對外確認(rèn)成功。電容放電。SSD板上的鉭電容或超級電容開始放電維持主控和DRAM的供電。這個能量極其寶貴因為下一步要用它把DRAM里的關(guān)鍵內(nèi)容搬到NAND。刷盤。固件在極短的時間內(nèi)把DRAM中的臟映射表、正在聚合的寫數(shù)據(jù)、事務(wù)日志按順序?qū)懭隢AND預(yù)留的緊急備份區(qū)。這個過程必須非常高效一個字節(jié)的電能浪費都可能造成cache無法完整落盤。安全收尾。刷盤成功后固件在NAND里標(biāo)記一個power loss recovery done之類的記錄然后讓設(shè)備進(jìn)入深度掉電。下次上電時固件讀到這個標(biāo)記就知道上次掉電是安全完成的只需要做正常的映射表導(dǎo)入。如果掉電發(fā)生在第3和第4步之間或者電容老化導(dǎo)致放電能量不足上電后固件就要去做重放恢復(fù)掃描NAND上的日志和備份區(qū)重建映射關(guān)系。這個過程可能持續(xù)幾秒到幾十秒期間SSD處于不可用的恢復(fù)中狀態(tài)SMART日志里的意外掉電計數(shù)也會增加。3.3 一次典型異常掉電事件的排查復(fù)盤有一回某客戶環(huán)境里一批盤在機(jī)房短暫斷電重啟后其中一塊變成了只讀狀態(tài)里面的數(shù)據(jù)庫完全打不開。管理人員第一時間覺得是顆粒壞了立刻換了盤。后來固件日志調(diào)出來才看到那次掉電后PLP恢復(fù)流程沒有正常完成電容健康狀態(tài)報警表明那塊盤在掉電瞬間沒有得到足夠的后備能量。這類問題在舊批次盤里并不少見。電容和電解電容一樣有壽命高溫環(huán)境下容量衰減尤其明顯。企業(yè)級盤的壽命計算不能只看NAND的擦寫次數(shù)PLP電容的老化同樣要作為失效模型納入考慮。這也是為什么很多廠商在盤的健康度指標(biāo)里專門區(qū)分了電容健康度和顆粒壽命兩個維度。你在Linux下用smartctl這類工具能直接看到類似Power_Loss_Cap_Test和Unexpected_Power_Loss計數(shù)的項這兩個值如果長期異常增長就是硬件層面的預(yù)警信號。4. 容量膨脹之后DRAM從幫手變成瓶頸4.1 映射表規(guī)模的算術(shù)題現(xiàn)在企業(yè)級SSD容量正從8TB、16TB向30TB以上邁進(jìn)QLC顆粒讓便宜大碗成為可能但DRAM開銷也跟著水漲船高。回到第一章的算術(shù)如果一塊8TB盤按16KB粒度映射光映射表就需要3GB到4GB DRAM。如果容量翻到32TB映射表直奔12GB以上。這個量級甚至超過許多臺式機(jī)的物理內(nèi)存不僅成本爆炸PCB空間也根本擺不下那么多DDR顆粒。廠商面臨兩難要么增大映射粒度承擔(dān)寫放大變高的代價要么把映射表壓縮成多級頁表靠更多的查表開銷換內(nèi)存容量要么干脆砍掉一部分全量映射只緩存熱數(shù)據(jù)映射冷數(shù)據(jù)動態(tài)加載——這又回到了緩存命中率的老問題。容量與映射粒度4KB粒度16KB粒度64KB粒度1TB約2GB約512MB約128MB8TB約16GB約4GB約1GB32TB約64GB約16GB約4GB上面的估算基于每個映射條目約8字節(jié)簡化了很多固件的壓縮和優(yōu)化空間但數(shù)量級足夠說明問題當(dāng)容量漲到幾十TB時靠多加幾顆DRAM來解決映射表存儲路越走越窄。4.2 成本、散熱與帶寬的疊加壓力DRAM并不是存儲行業(yè)里越來越便宜的部件。NAND顆粒每GB成本這些年一路走低DRAM卻因為工藝、產(chǎn)能和市場周期波動劇烈。對盤廠來說NAND顆粒是白菜價的話DRAM可能占掉整盤BOM的15%到25%大容量盤上這個比例更高。更麻煩的是盤要照顧散熱——DRAM持續(xù)刷新要耗電DDR4一條通道跑滿帶寬時功耗不是小數(shù)目企業(yè)級盤工作在機(jī)架式服務(wù)器里本來空氣就熱的DRAM數(shù)據(jù)在高溫下保留時間還會縮短固件可能又得提高刷新率功耗進(jìn)一步增加形成正反饋。很多盤把DRAM顆粒放在主控散熱片覆蓋范圍外但這也只是緩解不是解決。帶寬維度同樣吃緊。NAND接口速率從早期的400MT/s一路爬到2000MT/s以上主控內(nèi)部要同時處理NAND搬移、GC搬移、主機(jī)IO、DRAM讀寫DRAM通道往往成為最擠的那條路。一個極端場景SSD正在做大規(guī)模GC數(shù)據(jù)搬移同時主機(jī)又發(fā)來大量隨機(jī)讀請求。如果DRAM帶寬被搬移任務(wù)占用讀請求要么排隊等映射表加載要么在緩存里碰運氣。明顯網(wǎng)絡(luò)里的堵車吞吐掉下來只是表象尾延遲飆升才是企業(yè)存儲最怕的。4.3 業(yè)內(nèi)正在嘗試的幾條出路面對DRAM的壓力行業(yè)層面的解法基本圍繞三個方向。第一條路是映射數(shù)據(jù)瘦身。通過壓縮映射條目、稀疏索引、多級查表等手段把需要放在DRAM里的東西變小。代價是固件邏輯復(fù)雜度升高有時一次IO要多次訪問DRAM里的多級結(jié)構(gòu)CPU占用和隨機(jī)訪問次數(shù)都會增加。所以這條路是給大容量盤準(zhǔn)備的小盤做反而吃力不討好。第二條路是引入新介質(zhì)。以CXL為代表的內(nèi)存池化技術(shù)允許外部設(shè)備通過PCIe總線訪問主機(jī)或內(nèi)存池中的共享內(nèi)存。SSD主控可以把部分映射表外包給池化內(nèi)存從而減少板載DRAM容量需求。這本質(zhì)上是一種擴(kuò)展到主機(jī)側(cè)的HMB但比消費級HMB更規(guī)范、更強(qiáng)調(diào)隔離和安全。目前各家主控都在做原型驗證真正大規(guī)模商用還面臨延遲的一致性、故障隔離、安全邊界這些工程問題。第三條路是改變閃存管理模型。比如ZNSZoned Namespace通過把數(shù)據(jù)按順序?qū)懭氪髩K區(qū)域來減少映射表條目數(shù)量從根上降低元數(shù)據(jù)規(guī)模。這類架構(gòu)在QLC大容量盤的場景里很有吸引力因為它讓無大DRAM但映射表很小成為可能。不過它把更多控制權(quán)交給了主機(jī)軟件對現(xiàn)有應(yīng)用生態(tài)的改動是最大的阻力。說到底DRAM不是被淘汰了而是從大而全的緩存逐步轉(zhuǎn)向更精準(zhǔn)的索引。未來很長一段時間里企業(yè)級SSD依然離不開DRAM只是DRAM的容量和角色會隨著算法演進(jìn)被重塑。5. 關(guān)于DRAM我在研發(fā)和運維里踩過的一些坑5.1 選型時別只看標(biāo)稱順序讀寫評估一塊企業(yè)級SSD最容易被忽悠的指標(biāo)是順序讀寫和IOPS峰值。這些數(shù)字都是在干凈盤、高隊列深度、且IO模型與盤內(nèi)緩存策略剛好匹配時測出來的不能代表真實場景。實際選型時我建議至少做這幾類測試單隊列深度隨機(jī)4K讀、寫多隊列深度混合讀寫伴隨在線GC的持續(xù)壓力以及掉電恢復(fù)測試。用fio這類開源工具就能模擬大部分負(fù)載。比如模擬數(shù)據(jù)庫提交場景的隨機(jī)寫fio --namerandwrite_test --ioenginelibaio --rwrandwrite --bs4k \ --iodepth64 --direct1 --size40G --runtime600 --time_based \ --random_distributionzipf:1.2 --group_reporting跑一輪之后重點看兩個東西一是穩(wěn)態(tài)下的寫放大和尾延遲二是SMART里Unexpected_Power_Loss和介質(zhì)錯誤計數(shù)的變化趨勢。如果一塊盤在持續(xù)隨機(jī)寫半小時后P99延遲從幾十微秒抖到幾十毫秒不管峰值指標(biāo)多好看我都不會放進(jìn)生產(chǎn)環(huán)境。5.2 掉電測試不能只會拔電掉電保護(hù)驗證是整個存儲測試體系里最容易做假的地方。很多人測試時就是給SSD加個負(fù)載然后隨手把電源線一拔通電后看看盤還能不能掛載就結(jié)束。這樣做遠(yuǎn)遠(yuǎn)不夠。嚴(yán)謹(jǐn)?shù)牡綦姕y試至少需要覆蓋幾種模式在純讀負(fù)載下斷電、在純寫負(fù)載下斷電、在寫負(fù)載的不同階段斷電、在固件后臺GC運行的任意時刻斷電。還要控制掉電時機(jī)——最好用硬件控制電源的切/合閘時間讓斷電發(fā)生在某個IO正好提交完成、但等待狀態(tài)還沒有返回的邊界窗口。這個窗口才是PLP最容易暴露問題的位置。另外斷電后要等電容完全放電再重新上電不要立刻通電。有些盤的PLP流程依賴掉電后的殘余電壓如果上電太快主控還沒來得及完成電壓爬升可能出現(xiàn)復(fù)位時序紊亂人為造出假掉電失敗。提示掉電測試完成后檢查數(shù)據(jù)完整性不能只看文件系統(tǒng)能不能掛載要用寫盤前的hash列表逐一比對。一次完整的1000輪掉電循環(huán)測試通常能篩掉固件里大部分映射表一致性缺陷。5.3 運維視角關(guān)注這幾個指標(biāo)提前發(fā)現(xiàn)DRAM側(cè)隱患生產(chǎn)環(huán)境里DRAM相關(guān)的問題多數(shù)不是突然爆發(fā)的而是有前兆。最容易觀察的異常是SSD延遲毛刺。如果一塊舊盤在持續(xù)寫入時每隔一段時間就出現(xiàn)一次幾十毫秒的延遲尖峰SMART里又沒有新增壞塊那就要懷疑DRAM ECC糾錯或者刷新機(jī)制在高負(fù)載下出問題了。DDR顆粒本身會偶爾出現(xiàn)單比特翻轉(zhuǎn)企業(yè)級盤通常使用帶ECC的內(nèi)存主控可以糾正并記錄下來。如果能從日志里讀到單比特糾錯計數(shù)不斷上漲說明DRAM質(zhì)量可能正在劣化盡早做遷移和返修。另一個被很多人忽略的點是臟關(guān)機(jī)次數(shù)。SSD每次非正常下電都會把DRAM里的臟數(shù)據(jù)緊急刷回NAND這個過程消耗預(yù)留塊、消耗恢復(fù)帶寬。如果機(jī)房頻繁秒斷而不做安全關(guān)機(jī)盤上意外掉電計數(shù)會快速增長。雖然一次兩次問題不大但積累到成百上千次恢復(fù)邏輯就可能因為日志區(qū)和保留塊耗盡導(dǎo)致盤進(jìn)入只讀保護(hù)狀態(tài)。運維時給存儲節(jié)點配上可靠的UPS和軟件層優(yōu)雅關(guān)機(jī)流程比事后修盤有效得多。以我做過的一段經(jīng)驗來說DRAM不只是在性能測試?yán)飺螖?shù)值的部件它的健康狀態(tài)、溫度、ECC日志和掉電恢復(fù)計數(shù)應(yīng)當(dāng)被當(dāng)成和生產(chǎn)環(huán)境同樣的一等指標(biāo)來盯。尤其在大容量QLC盤逐漸普及的當(dāng)下DRAM容量的成本壓力會傳導(dǎo)到固件設(shè)計里出現(xiàn)更多少DRAM、多算法的折中方案運維人員對盤內(nèi)指標(biāo)的理解深度會直接影響能不能在故障發(fā)生前嗅到風(fēng)險。