2. 核心细节解析:16K IU的映射机制与设计取舍
1.1 IO架构为什么要变
以前做SSD固件的时候,映射管理基本都在4K粒度上做文章。4K是文件系统最常用的I/O大小,也是传统NAND页的最小写入单位,用4K做映射粒度,逻辑上非常顺——LBA直接整除4K就能算出对应的映射条目位置,CPU开销小,代码也简单。
但问题在容量上。映射条目本身也是要占DRAM的,一片8TB的SSD,按4K粒度做映射,单副本就要2GB左右的DRAM。消费级盘还能忍,数据中心和企业级盘动不动16TB、30TB起步,DRAM成本就压不住了。而且大容量盘往往跑的顺序读、顺序写场景更多,随机小I/O的比例反而在下降。在顺序I/O为主的工作负载下,还死守着4K映射粒度,DRAM白烧钱,性能也没有额外收益。
于是行业里开始提IU这个思路。IU全称Indirection Unit,你可以理解成映射管理的分页单位。它不是一个新概念,但16K这个粒度正在被越来越多的新主控采用,尤其在大容量SSD这个赛道上,16K IU几乎成了默认选择。
1.2 16K IU的映射原理
先理解IU的本质:它是Flash Translation Layer里的“映射桶”。传统4K映射是一个LBA对应一个映射条目,而16K IU是把16个连续的4K逻辑块打包成一个映射单元,只要这16个4K在物理上落在同一个16K对齐的物理块里,固件就只需维护一个映射条目。
具体来说,映射表的结构会变成两级:
code复制LBA → 一级映射(4K对齐的4K条目) → 二级映射(16K的IU单元)
第一次查找还是按4K粒度解析逻辑地址,但命中第二级之后,条目的物理地址是16K对齐的。如果主机写入是连续的16K数据,整条IU可以一次性更新,映射条目只在IU级别发生变更,不需要每一个4K都单独改一次映射项。
从DRAM占用上看,映射条目数直接除以4。还是以8TB盘为例,4K映射需要大约2GB DRAM,改成16K IU之后大约500MB就能搞定。对大容量主控来说,这个DRAM省下来的空间可以直接让给缓存、垃圾回收缓冲区或者做更大的写合并窗口。
1.3 动态映射与静态16K的差别
不少人对16K IU有个误解——以为它是固定把LBA按照16K切死,不考虑物理页的实际情况。实际上更成熟的方案是混合映射,或者叫动态IU选择。
NAND的物理页大小在TLC上是16KB,QLC上可能是16KB或更大(比如某些厂的24KB、32KB),如果IU固定16K但物理页是32K,读取时还是要拆成两次。所以当前比较务实的做法是:默认IU按16K对齐管理,当物理页恰好是16K时直接一一对应;当物理页大于16K时,固件会把多个16K IU合并到一个物理页,靠维护物理页内部的偏移信息来保证读写正确性。
好处显而易见:DRAM占用被压到很低,顺序写可以整页编程,不用做读-改-写。代价是碎片化管理的复杂度上来了,所以现在的固件基本都带一个选择器,会根据工作负载特征动态决定要不要把某个区域的映射粒度从16K收回到4K,比如随机小I/
