写放大,Write Amplification Factor,缩写WAF,这一术语最早是在2008年左右,由Intel公司和SiliconSystems公司(2009 年被西部数字收购)第一次在公开稿件中提出了并使用。WAF代表的含义就是NAND实际写入数据量与host写入量的比值,最理想的情况就是WAF=1,这个值越接近1越好。
linux环境的nvme ssd举例,可以通过nvme smart-log-add命令获取NAND和host写入量:
nvme smart-log-add /dev/nvme0
Additional Smart Log for NVME device:nvme0 namespace-id:ffffffff
key normalized raw
program_fail_count : 100% 0
erase_fail_count : 100% 0
wear_leveling : 62% min: 1114, max: 1161, avg: 1134
end_to_end_error_detection_count: 100% 0
crc_error_count : 100% 0
timed_workload_media_wear : 100% 37.941%
timed_workload_host_reads : 100% 51%
timed_workload_timer : 100% 446008 min
thermal_throttle_status : 100% 0%, cnt: 0
retry_buffer_overflow_count : 100% 0
pll_lock_loss_count : 100% 0
nand_bytes_written : 100% sectors: 16185227
host_bytes_written : 100% sectors: 6405605
要想完全理解写放大,我们需要先了解固态硬盘的读写机制。我们知道,固态硬盘的存储单元是由闪存颗粒组成的,无法实现物理性的数据覆盖,只能擦除然后写入,重复这一过程。因而,我们可以想象得到,在实际读写过程中,数据的读写势必会在闪存颗粒上进行多次的擦除写入,特别是当某些区块已经完全被塞满的情况下。
这些多次的操作,增加的写入数量和原始需要写入的数量的比值,就是所谓的写入放大。所以说,写入放大数值高,会损耗固态硬盘寿命。(固态硬盘闪存颗粒有着额定的P/E值,即最大的读写次数,写入放大高,P/E损耗快,寿命低。)在QLC介质中,WAF的影响更加致命。
举个例子,最坏情况下的,假如我要写入一个4KB的数据Z覆盖A,并恰好目标块没有空余的页区,需要进行GC回收。这个时候就需要把B、C、D、E、F五分数据都搬走,然后擦除整个数据块,擦除完成后再整体写入6个数据页。这个整个过程,Host虽然只写了4KB的数据,但实际过程中,由于GC的问题,NAND最终写入了24KB。那么写放大WAF=24KB/4KB=6.
影响WAF的因素:
SSD FTL算法的设计会影响写入放大的大小
Wear Leveling,WL磨损均衡:这一机制主要是通过均衡所有的闪存颗粒,从而延长整体的使用寿命,然而依旧是增加整体的写放大
Over-Provisioning,OP冗余空间:也会影响NAND写入的比例,最终影响写放大
Garbage Collection,GC垃圾回收:比如上面的例子,就是GC垃圾回收搬迁数据,擦除数据块后写入带来了整体写放大提升。
业务读写的数据模型:随机写和顺序写对NAND的写入比例有非常大的影响,直接影响写放大的系数
系统层的TRIM操作:会影响invalid无效数据是否在GC过程中搬迁,对写放大影响也有重要的作用。
写放大WAF是NAND-based SSD寿命消耗的关键参数,WAF越大,寿命消耗越快,越接近1,则寿命消耗越慢,也是最理想的情况。
所以,为了让SSD的WAF写放大系数接近1,这些年,各种方案也被提出来。
第一种优化写放大的方式:也是用的最多方式,就是增加OP冗余空间,降低WAF,提升寿命。比如根据Intel的白皮书信息来看,以P4510 4T为例
没有OP情况下,JEDEC标准压力下的DWPD=0.85
在OP 10%情况下,容量3.6T,DWPD上升到1.52,几乎翻了一倍。
在OP 20%情况下,容量3.2T,DWPD上升到2.27,接近原始容量的3倍。
JEDEC标准压力如下:
第二种优化写放大的方式:执行trim指令。
TRIM是SSD的一个特性,目的是让固态硬盘SSD在进行内部GC垃圾回收的时候,避免搬迁已经被OS删除的数据,减少无用的数据的搬迁从而降低写放大,提升SSD固态硬盘的寿命,同时也可以提升盘的有效带宽。
更多细节请参考:固态硬盘SSD格式化后,数据恢复的可能性有多大?
Linux内核态下常用fstrim完成系统的trim命令。在NVME协议中,trim有另外一个叫法:Deallocate,原理是一样的。
$ sudo /usr/sbin/fstrim --help
Usage:
fstrim [options] <mount point>
Discard unused blocks on a mounted filesystem.
Options:
-a, --all trim all supported mounted filesystems
-A, --fstab trim all supported mounted filesystems from /etc/fstab
-o, --offset <num> the offset in bytes to start discarding from
-l, --length <num> the number of bytes to discard
-m, --minimum <num> the minimum extent length to discard
-v, --verbose print number of discarded bytes
--quiet suppress error messages
-n, --dry-run does everything, but trim
-h, --help display this help
-V, --version display version
第三种优化写放大的方式:使用multi-stream的方案
从NVMe协议Spec 1.3开始新增的特性,Multi-stream write(多流写)技术可以使SSD根据主机端提供的Stream ID,将具有相同或相似生命周期的数据写入到相同的擦除单元中去,大大提高了GC时的效率,减少了写放大,使得SSD的性能和寿命都有了较大的提升。
更多细节请参考:浅析企业级SSD Multi-Stream Write技术
第四种优化写放大的方式:使用NVM sets和Endurance Group
在NVMe协议Spec 1.4中新增NVM sets和Endurance Group,不同的NVM Sets使用的不同的NAND物理资源,而且相互独立
每个NVM set又可以有多个namespace用户空间,不同的NVM sets读写之间不受干扰,可以有更好的IO稳定性。
同时,多个NVM sets可以组成一个Endurance Group,不同的业务压力模型写入不同的Endurance Group,整体降低数据的搬迁,降低写放大。
第五种优化写放大的方式:使用ZNS SSD
目的也是适配不同的业务场景,以最大的性价比完成性能/寿命/成本等多个因素的统一。
ZNS SSD的原理是把namespace空间划分多个zone空间,zone空间内部执行顺序读写。这样做的优势:
降低SSD内部的写放大,提升SSD的寿命
降低OP空间,host可以获得更大的使用空间
降低SSD内部DRAM的容量,降低整体的SSD成本
降低SSD读写延迟
ZNS写入了标准NVME协议,更易于打造软件生态,利于普及
更多细节请参考:炙手可热的ZNS SSD将会为数据中心带来什么?
第六种优化写放大的方式:SPDK WSR模型
基于WSR(Write-Shaping RAID)的写入对NAND非常友好,大块写且顺序,同时与SSD IU对齐。这样实现的方式从软件上做了彻底的优化,降低写放大。
整个WSR的数据流过程,主要有几个步骤:
第1步:数据会写写入WSR Bev
第2步:通过Append-only追加写的方式,写入数据到Optane SSD,同时基于VSS实现meta的安全校验,保证数据安全性。
第3步:更新软件管理的L2P映射表,这里面为了提升效果,热点访问的映射表放在DRAM,其他的放在Optane缓存盘。
第4步:通知用户完成写入。到这里跟用户之间的交互就完成了。
第5-7步:是后台执行的动作,Optane SSD中通过聚合/压缩等算法,形成大块顺序写场景,把数据下刷到QLC SSD,同时更新QLC对映的L2P映射表。
更多细节请参考:阿里云Optane+QLC存储实践案例分享
目前谷歌和Meta正在酝酿一件大事,希望把优化写放大的方式完成统一,并实现WAF接近1的目标。谷歌和Meta向NVME协议组织提交了Flexible Direct Placement TP4146提案,通过FDP的概念,可以把不同的workload写入不同的介质区间,写放大从3降低到1.
从目前已经公开的部分信息来看,FDP功能需要Host提供写入数据在NAND分布的提示,支持Standard Device Feature Enable/Disable和Host Enable Data / Media Alignment,对读操作没有影响,LBA放置也没有限制,支持XOR和多个namespace等。这个提案具体细节还没公布。看上去更像是NVM sets和Multi-Stream功能的技术融合,具体实现细节可能要等最终确定进入NVME Spec在说。有可能在NVME Spec 2.x就可以看到了。