读、写、擦除是ssd对nand的三大基本操作,但是针对nand自身的特性和多样化的i/o模型,ssd怎么读、写、擦除是门高级艺术,也由此衍生了很多技术。
比如垃圾回收(gc),一个优质的gc明白在什么时候,挑选哪些block,将上面的数据搬到哪去。
gc的基本原理
(如上图)左侧两个block中的有效数据被搬移/整合到一个新的block,然后这两个block将被擦除,形成两个可以写入数据的新block。
关于gc的研究,可以看memblaze金一同学的这个文章。
《gc算法与仿真原理解析》
有个问题,gc怎么才能知道垃圾是垃圾呢?讨论这个问题需要先回到数据存储的过程,开始是这样的。
当有数据删除之后,ssd并不能及时的知道谁是脏数据。形成了这样的局面
只有操作系统往标注del的位置上写数据时,盘才知道这是垃圾。
不然这些数据将一直被gc认为是有效数据搬移。为了更高效的执行gc,让操作系统和文件系统高效的和ssd主控交流删除文件的信息。
就出现了trim。
a trim command (known as trim in the ata command set, and unmap in the scsi command set) allows an operating system to inform a solid-state drive (ssd) which blocks of data are no longer considered in use and can be wiped internally.——wikipediahttps://en.wikipedia.org/wiki/trim_(computing)
维基百科给的这段介绍,在nvme ssd上解释就是,trim让操作系统通过trim命令(nvme协议中有定义)告诉ssd哪些地址上的数据可以擦除,从而提升垃圾回收的效率。
memblaze就是这么干的,
我们总结了trim的三大价值:
降低写放大
提升写性能
提高设备寿命
对于nvme来说,trim是让gc长了一对翅膀。说着简单,但是要通过trim达到降低写放大的目标而不影响设备性能,其中nand无效块的擦写时机、tirm和其他一系列ssd核心算法的配合非常有讲究。
trim实现难在哪这里就不详细讨论了,有兴趣的可以看ron写的文章《ssd trim 详解》
nvme spec对trim命令有详细的规定,所以使nvme cli就可以对trim功能进行验证
接下来就结合nvme spec的规定,发出我们的一条trim命令,然后做个验证。
1
准备设备和环境
使用memblaze官网pblaze5 910/916系列产品中的4t u.2nvme进行验证测试。
nvme list的信息如下 firmware version:001008r0
写入数据:从nvme 10gib的位置往后写10g的数据,数据pattern是0x12345678
[root@localhost~]#fio--thread--direct=1--allow_file_creat=0--ioengine=libaio--rw=write--bs=128k--iodepth=128--numjobs=1--name=nvme0n1--filename=/dev/nvme0n1--offset=10g--size=10g--verify=pattern--do_verify=0--verify_pattern=0x12345678nvme0n1:(g=0):rw=write,bs=(r)128kib-128kib,(w)128kib-128kib,(t)128kib-128kib,ioengine=libaio,iodepth=128fio-3.12starting1threadjobs:1(f=1):[w(1)][-.-%][w=3165mib/s][w=25.3kiops][eta00m:00s]nvme0n1:(groupid=0,jobs=1):err=0:pid=4787:monmar415:59:352019write:iops=25.2k,bw=3156mib/s(3309mb/s)(10.0gib/3245msec)slat(nsec):min=3204,max=81924,avg=9364.20,stdev=2437.54clat(usec):min=1177,max=17333,avg=5058.82,stdev=387.21lat(usec):min=1187,max=17347,avg=5068.25,stdev=387.16clatpercentiles(usec):|1.00th=[4555],5.00th=[5014],10.00th=[5014],20.00th=[5014],|30.00th=[5014],40.00th=[5014],50.00th=[5080],60.00th=[5080],|70.00th=[5080],80.00th=[5080],90.00th=[5080],95.00th=[5080],|99.00th=[5145],99.50th=[6063],99.90th=[11207],99.95th=[13042],|99.99th=[16909]bw(mib/s):min=3145,max=3166,per=100.00%,avg=3157.17,stdev=7.59,samples=6iops:min=25160,max=25334,avg=25257.33,stdev=60.68,samples=6lat(msec):2=0.11%,4=0.48%,10=99.30%,20=0.11%cpu:usr=3.73%,sys=25.09%,ctx=74895,majf=0,minf=13iodepths:1=0.1%,2=0.1%,4=0.1%,8=0.1%,16=0.1%,32=0.1%,>=64=99.9%submit:0=0.0%,4=100.0%,8=0.0%,16=0.0%,32=0.0%,64=0.0%,>=64=0.0%complete:0=0.0%,4=100.0%,8=0.0%,16=0.0%,32=0.0%,64=0.0%,>=64=0.1%issuedrwts:total=0,81920,0,0short=0,0,0,0dropped=0,0,0,0latency:target=0,window=0,percentile=100.00%,depth=128runstatusgroup0(alljobs):write:bw=3156mib/s(3309mb/s),3156mib/s-3156mib/s(3309mb/s-3309mb/s),io=10.0gib(10.7gb),run=3245-3245msecdiskstats(read/write):nvme0n1:ios=62/79409,merge=0/0,ticks=1/401029,in_queue=401403,util=96.86%[root@localhost~]#
2
依据nvme spec准备测试文件和命令
使用nvmecli将这10g的数据trim掉,利用强大的strace命令跟踪一下command的耗时,粗略的计算下trim的速度。
首先需要按照nvme spec协议中的dataset manager设置(如下图),创建一个4096byte的二进制文件。一个range最多trim32bit(0xffffffff*512byte 大约2047gib)的lba。
length in logical blocks和starting lba的计算
10g数据按照512byte的format格式得出是:
10*1024*1024*1024/512=20971520个(lba)
fio中offset=10g,因此start lba也是 :
10*1024*1024*1024/512=20971520
利用python创建二进制文件代码如下(简单的写个)
importarraybuf=array.array(b,[0x00]*4096)defsetvalue(buf,offset,num,value):#commonfunctiontosetunsignedintegervaluewithinthegivenrange#offset&numareinbytesforthisfunctionseries.ifnum==1:buf[offset]=valueelse:foriinxrange(num):buf[offset+i]=(value>>(8*i))&0xffreturnbufdefwritebinaryfile(buf,filepath):withopen(filepath,wb)asf:buf.tofile(f)#length in logical blocks :offset=4 num=4 value=20971520buf=setvalue(buf,4,4,20971520)#startinglbaoffset=8num=8value=20971520buf=setvalue(buf,8,8,20971520)writebinaryfile(buf,“/root/trim.bin”)
下面是nvme spec里trim命令的规范,使用nvmecli 发送nvme command需要照着填写
dword11 :二进制:0b 0100=0x04
3
准备工作做足了,接下来就是发!
发trim时候,在命令前加上strace –ttt,可以粗略的计算trim的速度。
[root@localhost~]#strace–tttnvmeio-passthru/dev/nvme0--opcode=0x09--namespace-id=1--cdw10=0x00--cdw11=0x04--input-file=trim.bin--data-len=4096–write
我们经过计算得出trim耗时0.00124s,所以trim的速度大约是:10 /0.00124= 8064.516gib/s 大约8tb/s
4
trim后立即数据验证
[root@localhost~]#fio--thread--direct=1--allow_file_creat=0--ioengine=libaio--rw=read--bs=128k--iodepth=128--numjobs=1--name=nvme0n1--filename=/dev/nvme0n1--offset=10g--size=10g--verify=pattern--do_verify=1--verify_pattern=0x00nvme0n1:(g=0):rw=read,bs=(r)128kib-128kib,(w)128kib-128kib,(t)128kib-128kib,ioengine=libaio,iodepth=128fio-3.12starting1threadjobs:1(f=1):[v(1)][-.-%][r=3176mib/s][r=25.4kiops][eta00m:00s]nvme0n1:(groupid=0,jobs=1):err=0:pid=9241:monmar421:37:352019read:iops=25.4k,bw=3171mib/s(3325mb/s)(10.0gib/3229msec)slat(usec):min=9,max=225,avg=11.21,stdev=3.14clat(usec):min=1938,max=11585,avg=5010.57,stdev=1313.65lat(usec):min=1948,max=11595,avg=5021.85,stdev=1313.57clatpercentiles(usec):|1.00th=[2147],5.00th=[2868],10.00th=[3294],20.00th=[3884],|30.00th=[4293],40.00th=[4621],50.00th=[4948],60.00th=[5342],|70.00th=[5735],80.00th=[6194],90.00th=[6783],95.00th=[7242],|99.00th=[8029],99.50th=[8225],99.90th=[8717],99.95th=[9110],|99.99th=[9765]bw(mib/s):min=3168,max=3176,per=100.00%,avg=3172.88,stdev=3.26,samples=6iops:min=25348,max=25410,avg=25383.00,stdev=26.07,samples=6lat(msec):2=0.47%,4=22.76%,10=76.75%,20=0.01%cpu:usr=45.94%,sys=29.43%,ctx=22554,majf=0,minf=25iodepths:1=0.1%,2=0.1%,4=0.1%,8=0.1%,16=0.1%,32=0.1%,>=64=99.9%submit:0=0.0%,4=100.0%,8=0.0%,16=0.0%,32=0.0%,64=0.0%,>=64=0.0%complete:0=0.0%,4=100.0%,8=0.0%,16=0.0%,32=0.0%,64=0.0%,>=64=0.1%issuedrwts:total=81920,0,0,0short=0,0,0,0dropped=0,0,0,0latency:target=0,window=0,percentile=100.00%,depth=128runstatusgroup0(alljobs):read:bw=3171mib/s(3325mb/s),3171mib/s-3171mib/s(3325mb/s-3325mb/s),io=10.0gib(10.7gb),run=3229-3229msecdiskstats(read/write):nvme0n1:ios=79930/0,merge=0/0,ticks=394735/0,in_queue=395214,util=96.95%[root@localhost~]#
可以看到加上--verify_pattern=0x00之后,err= 0,证明trim后数据都变成0了,至于更细节的说明,在此不再赘述。
通过一系列的介绍和实验验证,我们看到了trim的价值和实现原理。在trim的帮助下,nvme ssd的gc等操作效率更高,进而达到降低写放大,提高产品性能和寿命的效果。
防爆电磁阀的分类_防爆电磁阀材质分类
NDIR气体传感器的工作原理解析
Yonghong Desktop数据分析全解决?七大核心亮点分析
iPhone XI概念机亮相,LG首款5G手机4月19日开卖
电动车的控制器故障与维修
读、写、擦除是SSD对NAND的三大基本操作
我国发布全球首个商业化自动驾驶出租车标准
通用GPU的概念和特点
展望十四五,中航锂电产能将超过200GWh
前沿科技亲密接触 那些你不知道的汽车雷达测试
每日一课 | 智慧灯杆的公共广播功能有哪几种实际应用场景?
低功耗医学数据记录仪的设计
银川推出既有住宅加装直线马达电梯新政策
带隔离和不带隔离的开关电源的区别
电路板脏了?如何清洗?
Manz亚智科技宣布与顶尖自动分析管理装置制造商EIKO技术战略合作
2019年底加密货币市场上约有25%的项目将采用POS共识作为安全模型
I2C接口的上拉电阻问题
高通控告苹果赢首胜 苹果须偿付3,160万美元赔偿
智能音箱的浪潮已来,中国电信也在赋予行动