化實(shí)踐:L2P映射表硬件加速、GC與駐留策略深度解析)
干過SSD固件或者存儲(chǔ)系統(tǒng)底層的人應(yīng)該都有過這樣的體會(huì)整個(gè)FTLFlash Translation Layer里最讓人又愛又恨的東西就是L2P映射表。說它讓人愛是因?yàn)樗羞壿嫷刂返轿锢淼刂返霓D(zhuǎn)換都靠它主機(jī)的讀寫請(qǐng)求能不能命中全看這張表查得快不快、準(zhǔn)不準(zhǔn)說它讓人恨是因?yàn)橐坏┤萘可先ァ⒉l(fā)一高、GC一啟動(dòng)這張表就會(huì)變成性能瓶頸的“集火點(diǎn)”。我這兩年正好在折騰L2P表相關(guān)的優(yōu)化工作從硬件數(shù)據(jù)通路的搭建到GC過程中VPC表的構(gòu)建瓶頸再到運(yùn)行時(shí)駐留策略的調(diào)整踩了不少坑也沉淀了一些可以復(fù)用的思路這篇就把我的實(shí)踐過程完整拆開講一講。這篇內(nèi)容主要圍繞三個(gè)核心問題展開第一L2P表為什么需要專門的硬件級(jí)數(shù)據(jù)通路來做查表和更新第二垃圾回收GC場(chǎng)景下VPC表的構(gòu)建瓶頸到底卡在哪里怎么破第三在DRAM和SRAM資源都受限的實(shí)際產(chǎn)品里L(fēng)2P表運(yùn)行時(shí)駐留策略應(yīng)該怎么設(shè)計(jì)。做SSD固件、存儲(chǔ)控制器驗(yàn)證、以及研究FTL算法的朋友都可以在里邊找到一些可以直接落地的參考方案。1. L2P表為什么值得一條硬件級(jí)數(shù)據(jù)通路L2P表說白了就是一張記錄了“邏輯地址到物理地址”對(duì)應(yīng)關(guān)系的表。主機(jī)下發(fā)一個(gè)讀命令控制器得先根據(jù)邏輯地址LBA去查這張表拿到物理地址之后才能去對(duì)應(yīng)的Flash位置讀數(shù)據(jù)。寫命令則反過來先分配一個(gè)物理頁然后把新的映射關(guān)系更新到表里。很多人覺得查表不就是一個(gè)內(nèi)存讀取操作嘛有什么好講的但真正放到高并發(fā)、低延遲的NVMe SSD場(chǎng)景下事情遠(yuǎn)沒有那么簡單。固件跑在控制器內(nèi)置的CPU核上這個(gè)核的性能比我們平時(shí)用的應(yīng)用處理器差不少頻率低、核數(shù)少。主機(jī)側(cè)可能同時(shí)壓著幾十K甚至上百K的IOPS每一條IO都要走一遍L2P查表。如果這一步完全靠CPU軟件去查CPU資源很快就會(huì)被吃光留給GC搬運(yùn)、磨損均衡、壞塊管理這些后臺(tái)任務(wù)的算力就所剩無幾了。更麻煩的是軟件查表還要經(jīng)過總線讀寫緩存延遲高且不可控導(dǎo)致IO延遲抖動(dòng)明顯。所以業(yè)界的通用做法就是把L2P的查找和數(shù)據(jù)搬運(yùn)從CPU手里拿出去專門用硬件邏輯來實(shí)現(xiàn)這就是硬件級(jí)數(shù)據(jù)通路的由來。1.1 L2P硬件數(shù)據(jù)通路的整體形態(tài)一條完整的硬件數(shù)據(jù)通路通常包含命令解析模塊、L2P查找引擎、表項(xiàng)緩存、DRAM控制器接口和結(jié)果返回通路。主機(jī)命令進(jìn)來之后先由硬件解析出邏輯地址然后查找引擎拿著這個(gè)邏輯地址去查映射表拿到物理地址后要么直接去訪問Flash要么把結(jié)果返回給固件做后續(xù)處理。這里有一個(gè)關(guān)鍵的設(shè)計(jì)點(diǎn)L2P表本身是放在DRAM里的而DRAM訪問有延遲。如果每一條IO都直接去DRAM里查表DRAM帶寬會(huì)成為新的瓶頸。所以必須在硬件查找引擎和DRAM之間加一層片上緩存通常用SRAM實(shí)現(xiàn)緩存最近訪問過的映射表項(xiàng)原理跟CPU的TLB是一回事。我測(cè)試過一組數(shù)據(jù)加了SRAM緩存之后L2P查詢的命中率能達(dá)到90%以上平均查詢延遲比直接訪問DRAM低了一半還多。1.2 硬件查表應(yīng)該用什么數(shù)據(jù)結(jié)構(gòu)這一點(diǎn)特別容易被做成軟件方案的簡單平移然后發(fā)現(xiàn)在硬件上行不通。軟件環(huán)境里L(fēng)2P表用哈希表或者多級(jí)頁表都行因?yàn)镃PU處理哈希沖突很靈活。但硬件邏輯做哈希沖突處理非常痛苦邏輯復(fù)雜度直線上升時(shí)序收斂也難。所以我在實(shí)際項(xiàng)目里更推薦定長多級(jí)表或者基于Radix樹的硬件友好結(jié)構(gòu)。定長多級(jí)表的思路是把邏輯地址拆成多段每一段作為一級(jí)索引最后一級(jí)條目指向物理頁地址。這樣查找路徑固定硬件流水線非常好做每個(gè)周期都能發(fā)起一次查找。缺點(diǎn)是可能存在內(nèi)部碎片大容量場(chǎng)景下內(nèi)存利用率略低。但考慮到現(xiàn)在控制器的DRAM容量普遍在GB級(jí)別映射表多占用的那幾百M(fèi)B完全在可接受范圍內(nèi)。哈希方案不是不行但它的平均性能雖然好最壞情況下沖突嚴(yán)重時(shí)會(huì)卡住流水線對(duì)需要穩(wěn)定延遲的存儲(chǔ)場(chǎng)景不太友好。1.3 硬件數(shù)據(jù)通路設(shè)計(jì)中的幾個(gè)關(guān)鍵細(xì)節(jié)設(shè)計(jì)硬件數(shù)據(jù)通路時(shí)有幾個(gè)坑是我實(shí)際踩過之后才反應(yīng)過來的這里重點(diǎn)提醒一下。第一表項(xiàng)更新和IO查詢之間有并發(fā)一致性問題。主機(jī)在讀數(shù)據(jù)的同時(shí)固件可能正在后臺(tái)更新同一批映射表項(xiàng)比如GC搬移完數(shù)據(jù)之后要改映射。如果硬件查詢引擎讀到了更新前的舊表項(xiàng)就會(huì)拿到一個(gè)已經(jīng)無效的物理地址。解決思路是給映射表項(xiàng)加版本號(hào)或者有效位固件更新前先做表項(xiàng)失效操作查詢引擎發(fā)現(xiàn)失效后把這條查詢請(qǐng)求踢回給固件軟件處理。第二回寫路徑的順序保障。L2P表項(xiàng)的更新必須嚴(yán)格保序。比如主機(jī)連續(xù)寫兩個(gè)扇區(qū)邏輯地址相同第一次寫的映射結(jié)果如果沒有落表第二次寫的映射結(jié)果先落了表那就會(huì)導(dǎo)致映射指向新數(shù)據(jù)而舊數(shù)據(jù)尚未標(biāo)記無效掉電時(shí)數(shù)據(jù)一致性就崩了。硬件通路里需要有一個(gè)FIFO隊(duì)列保證同地址表項(xiàng)的更新按提交順序執(zhí)行。第三異常返回路徑。硬件查表不是每次都能成功的比如映射表項(xiàng)不在緩存里或者目標(biāo)表項(xiàng)還沒分配。設(shè)計(jì)的時(shí)候必須留一條exception路徑把這種查詢請(qǐng)求導(dǎo)回給固件做軟件處理。還有就是從Flash讀映射表的場(chǎng)景映射表本身也放在Flash里冷啟動(dòng)時(shí)要把整張表加載到DRAM這個(gè)加載過程也最好做成硬件DMA搬運(yùn)否則啟動(dòng)時(shí)間會(huì)很難看。2. GC里的VPC表瓶頸到底在哪GCGarbage Collection是FTL里繞不開的環(huán)節(jié)它的作用是回收那些寫滿數(shù)據(jù)、但已有部分頁失效的物理塊。GC要做的事情概括起來就三步選塊、搬移有效頁、擦除物理塊。而選塊和搬移過程中VPC表就是那個(gè)決定效率和寫入放大系數(shù)的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)。VPC表全稱Valid Page Count Table記錄的是每個(gè)物理塊當(dāng)前還有多少個(gè)有效頁。GC每次要挑一個(gè)塊來回收按什么標(biāo)準(zhǔn)挑最樸素的標(biāo)準(zhǔn)就是挑VPC最小的塊因?yàn)橛行ы撛缴傩枰嵋频臄?shù)據(jù)量越小額外寫入越少。這個(gè)邏輯說起來簡單但VPC表本身的構(gòu)建和維護(hù)在高容量SSD里會(huì)成為很重的負(fù)擔(dān)。2.1 VPC表的構(gòu)建過程為什么慢構(gòu)建VPC表的核心操作是從L2P表反向推導(dǎo)每個(gè)物理塊的有效頁數(shù)量。具體做法是遍歷L2P表的所有條目每一條映射拿到它的物理頁地址然后把這個(gè)地址所屬的物理塊的計(jì)數(shù)器加一。等到整張L2P表掃完每個(gè)物理塊的VPC就等于它的計(jì)數(shù)器的值。問題出在這個(gè)“遍歷”上。L2P表動(dòng)輒幾百萬條條目每條都對(duì)應(yīng)一次內(nèi)存讀取和一次計(jì)數(shù)器增量。如果這個(gè)流程用CPU軟件實(shí)現(xiàn)需要花費(fèi)非常長的時(shí)間。而且這不只是時(shí)間問題——遍歷L2P表的同時(shí)會(huì)產(chǎn)生大量的CPU緩存未命中因?yàn)橛成浔項(xiàng)l目在內(nèi)存里的分布是隨機(jī)的你剛讀完地址A下一個(gè)地址B很可能落在很遠(yuǎn)的位置。有次我在調(diào)試環(huán)境里測(cè)過用軟件方式掃描一份容量約1TB的L2P表耗時(shí)超過3秒GC期間主機(jī)的IO差不多要停擺這種體驗(yàn)在產(chǎn)品里完全不可接受。2.2 GC過程中VPC表選塊策略的另一種思路傳統(tǒng)的VPC掃描選塊是一種離線、靜態(tài)的方式也就是GC發(fā)起時(shí)臨時(shí)掃描全表。掃描成本高之外還有一個(gè)問題掃描得到的VPC是某一瞬間的快照等真正搬移數(shù)據(jù)的時(shí)候又有不少頁因?yàn)樾聦懙腎O或主機(jī)的更新操作變成無效了。快照和實(shí)際之間始終存在誤差如果誤差方向是“預(yù)估有效頁偏少”那GC搬移時(shí)會(huì)額外搬一些其實(shí)已經(jīng)失效的頁寫入放大就上去了。更好的方案是維護(hù)增量式VPC。也就是在正常IO路徑上動(dòng)態(tài)維護(hù)每個(gè)物理塊的VPC每次寫分配時(shí)新分配的物理頁對(duì)應(yīng)的塊VPC加一每次表項(xiàng)更新導(dǎo)致舊物理頁失效時(shí)對(duì)應(yīng)的塊VPC減一。這樣VPC表始終是實(shí)時(shí)的選塊的時(shí)候直接查表就行完全不需要掃描碎片。這看起來很簡單但它要求每一次IO的映射更新都必須同步維護(hù)VPC計(jì)數(shù)器。VPC表本身放在DRAM里那意味著每次映射更新都多了一次VPC表的讀寫操作。如果不能和L2P表更新合并為一次原子操作性能開銷就會(huì)翻倍。我實(shí)際采用的折中方案是VPC表不用精確值采用周期性校準(zhǔn)。具體做法是在平時(shí)用增量維護(hù)保持一個(gè)近似的VPC值GC選塊的時(shí)候用近似值做粗選選出候選塊之后再做一次小范圍的精確掃描只掃描這幾十個(gè)候選塊的映射關(guān)系確認(rèn)它們各自的真實(shí)有效頁數(shù)。這樣既避免了全表掃描的開銷又能保證GC選出來的塊是足夠優(yōu)秀的寫入放大也能控制在可接受范圍。2.3 硬件并行掃描對(duì)GC的有效加速即使采用上面說的粗選加精選方案GC過程中的精確校準(zhǔn)步驟還是需要掃描一部分映射表數(shù)據(jù)。這部分工作我建議做成硬件模塊不要占用CPU。思路是這樣的硬件掃描引擎從DRAM里按順序讀L2P表的高位段提取出物理塊號(hào)然后在一個(gè)片上計(jì)數(shù)器陣列里做增量。因?yàn)閽呙枋沁B續(xù)內(nèi)存訪問硬件可以一次性突發(fā)讀很多條映射表?xiàng)l目再做流水線式處理吞吐量比CPU逐條掃描高好幾倍。我還在這條通路里判斷了跳過條件——如果某一段邏輯地址區(qū)間對(duì)應(yīng)的物理塊號(hào)全部落在同一批候選塊里就只更新這幾個(gè)計(jì)數(shù)避免不必要的比較。實(shí)測(cè)下來改用硬件掃描引擎之后候選塊校準(zhǔn)時(shí)間從原來的幾百毫秒縮到了幾十毫秒GC停IO的窗口大幅縮短。對(duì)前臺(tái)主機(jī)IO的影響明顯變小QoS數(shù)據(jù)好看了不少。3. L2P表運(yùn)行時(shí)駐留策略內(nèi)存放不下的取舍前面說的都是L2P表“怎么查”的問題接下來還有一個(gè)更現(xiàn)實(shí)的問題L2P表放哪兒、留多少。消費(fèi)級(jí)SSD控制器里的SRAM通常只有幾MB到幾十MBDRAM也就幾百M(fèi)B到幾GB。而L2P表的大小跟SSD容量成正比。以4KB映射粒度為例1TB的SSD有2.68億個(gè)邏輯頁每個(gè)映射表項(xiàng)假設(shè)壓縮后占8字節(jié)那么表本身接近2GB。這還沒算元數(shù)據(jù)和日志占用的空間。也就是說大容量產(chǎn)品里L(fēng)2P表根本不可能全量放進(jìn)片上SRAM甚至連只放在DRAM里都是個(gè)奢侈的選擇。容量越大駐留策略越關(guān)鍵。3.1 全表駐留、部分駐留和分級(jí)駐留的適用場(chǎng)景駐留策略可以分為三個(gè)層級(jí)全表駐留就是把所有映射表?xiàng)l目都放在DRAM里。優(yōu)點(diǎn)是查找路徑最簡單不存在換入換出的問題缺點(diǎn)是DRAM容量開銷大而且掉電時(shí)整張表都要靠電容電量保住否則重建映射會(huì)耗時(shí)極長。這個(gè)方案在早期小容量SSD里很流行現(xiàn)在則主要用于企業(yè)級(jí)高端盤因?yàn)槟切┍PDRAM加得足夠多。部分駐留則是當(dāng)映射表總大小超過DRAM可用空間時(shí)只把一部分表項(xiàng)放DRAM其余部分留在Flash里需要時(shí)再換入。這相當(dāng)于給L2P表做了一套二級(jí)存儲(chǔ)體系。難點(diǎn)在于換入換出策略怎么定——換錯(cuò)了會(huì)頻繁觸發(fā)Flash讀映射表那性能和隨機(jī)寫時(shí)會(huì)出現(xiàn)的卡頓會(huì)比想象中嚴(yán)重得多。分級(jí)駐留是我個(gè)人認(rèn)為在容量、性能和成本之間平衡得最好的方案。頂層是一小塊片上SRAM存最近訪問過的映射表項(xiàng)中間層是普通DRAM存放常駐工作集底層是Flash里的系統(tǒng)區(qū)存完整映射表。SRAM命中走硬件快路徑DRAM命中走正常的硬件查找兩者都不中才回退到Flash加載。這種結(jié)構(gòu)能讓絕大多數(shù)IO只命中前兩級(jí)有效規(guī)避了Flash讀映射表的高延遲。3.2 熱點(diǎn)表項(xiàng)識(shí)別與緩存替換策略分級(jí)駐留方案的核心模塊是SRAM緩存層而緩存替換策略基本上決定了整個(gè)L2P查詢的命中率。我一開始用的是最簡單的LRULeast Recently Used但很快發(fā)現(xiàn)隨機(jī)寫場(chǎng)景下LRU表現(xiàn)很差。原因是隨機(jī)寫的映射表項(xiàng)更新很分散每一條新表項(xiàng)被訪問過一輪之后很快就會(huì)被趕出緩存下次再寫同一條地址時(shí)緩存已經(jīng)失效了。明明整個(gè)表只有幾萬個(gè)熱點(diǎn)表項(xiàng)緩存容量卻一直在被冷門表項(xiàng)擠占。后來我改成了被反復(fù)驗(yàn)證過的ARCAdaptive Replacement Cache思路。ARC把緩存分成Recent區(qū)和Frequent區(qū)Recent區(qū)管新出現(xiàn)的表項(xiàng)Frequent區(qū)管經(jīng)常被訪問的表項(xiàng)。當(dāng)一個(gè)表項(xiàng)在短期內(nèi)連續(xù)兩次被訪問就把它從Recent區(qū)提升到Frequent區(qū)避免被新進(jìn)入的表項(xiàng)擠掉。這個(gè)策略對(duì)存儲(chǔ)場(chǎng)景特別適用因?yàn)閷?shí)際業(yè)務(wù)里的訪問模式往往是“熱點(diǎn)相對(duì)集中、冷熱交替出現(xiàn)”的。這個(gè)改動(dòng)的效果非常直觀。在我測(cè)的隨機(jī)寫模型里SRAM命中率從原來的82%提升到了94%左右平均IO延遲下降了差不多三成。而且ARC比LRU對(duì)突發(fā)訪問模式的適應(yīng)性更強(qiáng)GC搬移大批映射表項(xiàng)時(shí)不會(huì)被臨時(shí)的突發(fā)訪問打亂熱點(diǎn)分布。3.3 臟映射表項(xiàng)的回寫和掉電保護(hù)L2P表運(yùn)行時(shí)駐留策略還有一個(gè)不能忽略的維度臟表項(xiàng)。所謂臟表項(xiàng)就是更新過但還沒寫回Flash的映射表?xiàng)l目。這部分?jǐn)?shù)據(jù)只存在于SRAM或DRAM里如果突然掉電這些映射會(huì)全部丟失之后只能靠日志或全盤掃描重建非常耗時(shí)。掉電保護(hù)的核心思路是日志先行也就是新映射產(chǎn)生時(shí)先寫一條映射更新日志到Flash日志寫成功之后才算真正持久化。緩存里的臟表項(xiàng)什么時(shí)候落盤有幾種觸發(fā)條件一是緩存容量到達(dá)閾值需要替出臟表項(xiàng)時(shí)強(qiáng)制執(zhí)行二是周期性后臺(tái)刷盤三是GC搬移過程中涉及到的映射更新優(yōu)先落盤避免GC完成之后掉電造成映射不一致。我在實(shí)際調(diào)優(yōu)中發(fā)現(xiàn)臟表項(xiàng)的累積速率和刷盤頻率之前存在很強(qiáng)的耦合關(guān)系。如果刷盤太頻繁Flash寫入放大增加如果刷盤太慢掉電時(shí)緩存里的臟表項(xiàng)太多重建時(shí)間會(huì)超出規(guī)格。平衡點(diǎn)建議根據(jù)實(shí)際IO負(fù)載來設(shè)比如在寫密集型的測(cè)試模型里刷盤水位線設(shè)在緩存容量的60%比較合適水位線到80%時(shí)觸發(fā)強(qiáng)制回寫盡量避免緩存被臟表項(xiàng)擠占而影響新映射的寫入。4. 常見問題排查與實(shí)操心得這幾部分工作做下來積累了一些實(shí)際調(diào)試中遇到的典型問題單獨(dú)寫一節(jié)順便分享一些我的排查習(xí)慣。這些問題在文檔里不一定寫得很清楚但遇到的時(shí)候都很要命。4.1 硬件查表通路返回錯(cuò)誤映射的排查最詭異的一類問題就是硬件返回的物理地址在錯(cuò)誤的時(shí)間點(diǎn)是對(duì)的在某個(gè)極端時(shí)序下卻是錯(cuò)的。這種問題通常不是邏輯錯(cuò)誤而是流水線上有先后的競態(tài)。我排查的順序是先查命令隊(duì)列深度打滿時(shí)的行為再查同地址亂序更新場(chǎng)景最后用形式化驗(yàn)證工具跑一遍斷言。簡單點(diǎn)說如果懷疑硬件返回了舊映射可以在硬件通路里加一個(gè)比較器每一條查詢返回時(shí)都跟固件維護(hù)的軟件映射副本做比對(duì)不一致就記錄上下文。壞處是這會(huì)在調(diào)試版本里多耗不少資源但換來的是一條能在真實(shí)場(chǎng)景里精準(zhǔn)抓到異常現(xiàn)場(chǎng)的調(diào)試通路值。4.2 GC選塊和VPC維護(hù)的常見坑VPC計(jì)數(shù)器維護(hù)里最容易出現(xiàn)的坑是計(jì)數(shù)漂移。增量維護(hù)的VPC因?yàn)槟炒萎惓A鞒搪p了以后就會(huì)一直偏大。出現(xiàn)這種情況就很難排查因?yàn)橛?jì)數(shù)器差值不固定GC選塊的行為也會(huì)慢慢變得不優(yōu)。我的建議是定期做一次全盤校準(zhǔn)哪怕不做精確掃描也可以按物理塊抽樣校驗(yàn)發(fā)現(xiàn)偏差超限就把對(duì)應(yīng)塊的VPC重新算一遍。另一個(gè)坑是GC搬移過程中搬出的數(shù)據(jù)寫到了目標(biāo)塊目標(biāo)塊的VPC加一但源塊那個(gè)有效頁應(yīng)該在搬完之后標(biāo)記失效并減一。這個(gè)“搬完再減”的順序千萬不能反否則掉電恢復(fù)之后會(huì)出現(xiàn)同一個(gè)邏輯頁同時(shí)映射到兩個(gè)物理頁的異常狀態(tài)。我們固件代碼里把這兩個(gè)操作寫成了一個(gè)原子事務(wù)要么都完成要么都回滾保證恢復(fù)時(shí)不會(huì)出現(xiàn)雙映射。4.3 駐留策略引起的QoS毛刺L2P表部分駐留策略下最頭疼的副作用是QoS毛刺。想象一下主機(jī)正在跑穩(wěn)定的隨機(jī)寫IO突然來了一波冷數(shù)據(jù)寫的請(qǐng)求這些地址的映射表項(xiàng)不在緩存里需要從Flash重新?lián)Q入換入的過程里IO延遲直接飆升好幾毫秒。對(duì)延遲敏感的企業(yè)級(jí)業(yè)務(wù)來說這種毛刺比平均延遲高更加致命。緩解的辦法是在換入路徑上做預(yù)取。當(dāng)緩存未命中觸發(fā)一次Flash讀映射表時(shí)順帶把該邏輯地址附近的一組映射表?xiàng)l目一起讀上來。因?yàn)镮O訪問通常有局部性相鄰地址的映射大概率也會(huì)在不久后被用到。這個(gè)預(yù)取粒度要根據(jù)映射表在Flash上的排列方式設(shè)計(jì)不要貪多一次讀太多會(huì)吃掉Flash帶寬反而拖慢正常IO。另外還可以設(shè)計(jì)一條“慢路徑旁路”機(jī)制當(dāng)緩存未命中需要從Flash換入時(shí)主機(jī)IO不阻塞等待先走一個(gè)低優(yōu)先級(jí)的異步加載流程同時(shí)立即返回一個(gè)超時(shí)重試指示讓主機(jī)稍后重試。這個(gè)機(jī)制在NVMe協(xié)議里有對(duì)應(yīng)的狀態(tài)碼可以實(shí)現(xiàn)缺點(diǎn)是增加了主機(jī)側(cè)的交互復(fù)雜度是否采用要權(quán)衡產(chǎn)品定位。4.4 實(shí)測(cè)數(shù)據(jù)駐留策略調(diào)整前后對(duì)比最后給一組我在真實(shí)測(cè)試環(huán)境里拿到的數(shù)據(jù)方便大家有個(gè)直觀感知。測(cè)試模型是64KB隨機(jī)寫、隊(duì)列深度32、SSD標(biāo)稱容量2TB映射粒度4KBSRAM緩存配置為8MB。調(diào)整前的策略是LRU、無預(yù)取、臟表項(xiàng)水位線50%實(shí)測(cè)平均IO延遲78微秒P99延遲4.2毫秒SRAM命中率82%。調(diào)整后的策略是ARC替換策略、帶8KB映射預(yù)取、臟表項(xiàng)水位線60%實(shí)測(cè)平均IO延遲55微秒P99延遲1.8毫秒SRAM命中率94%。P99延遲降了57%這個(gè)數(shù)字對(duì)上線產(chǎn)品的體驗(yàn)提升是非常可感的。這個(gè)對(duì)比也說明一個(gè)問題L2P表運(yùn)行時(shí)駐留策略不是簡單選一種算法就完了替換策略、預(yù)取粒度、刷盤水位這些參數(shù)要放在一起調(diào)相互配合才能拿到最優(yōu)解。單獨(dú)調(diào)任何一個(gè)都很難有質(zhì)的提升甚至可能互相抵消。再往深了說L2P表這一系列優(yōu)化做完之后GC效率也跟著上來了。因?yàn)橛成涓驴炝薌C搬移時(shí)更新映射的開銷就低VPC選塊準(zhǔn)了搬移次數(shù)就少駐留命中率高了GC過程中額外讀映射表的次數(shù)就少。三者是環(huán)環(huán)相扣的單獨(dú)優(yōu)化某一塊很難見效必須放在一起做整體設(shè)計(jì)。我在調(diào)試過程中一度只盯著駐留策略調(diào)結(jié)果GC性能上不去后來把VPC維護(hù)邏輯和硬件掃描通路一起改了問題才徹底解決。存儲(chǔ)系統(tǒng)的性能優(yōu)化從來不是一個(gè)點(diǎn)的事而是整條鏈路的事。