# nvme format /dev/nvme0n1 -n 1 -l 2 -i 1 -m 1 -p 1
这是一条nvmecli的format命令,需要指出的是这条命令会打开PBlaze5 系列NVMe SSD端到端数据保护功能。当下,端到端数据保护技术已经是PBlaze5 910/916,以及PBlaze5 920系列中成熟的数据保护技术,并且Memblaze实现了不同大小的sector 和元数据组合方案(Viable Sector Size Management,下文简称“VSS”),可以根据客户的业务需求设计优化配置。
之前,我们侧重于端到端数据保护技术的原理介绍,比如《企业级的数据链路保护是什么?》,这篇我们主要通过实验和命令,解读PBlaze5 920系列NVMe SSD的端到端数据保护方案的实现和验证。
Host正确无误的将一个a写到NAND上,并在需要的时候将a正确的读出来,这件事看似基础,并且十分必要(显然只有读上来的是正确数据才有价值)。但是对于SSD而言却有很多挑战,SSD的软硬件缺陷、温度乃至一些射线等不确定因素都可能会导致出错。
有些错误通过LDPC等纠错机制就可以发现和纠正,但是也有极少数错误不能通过这些常规的机制检测出来,被称为静默错误(Silent Data Error),这部分错误虽然极少但是对于金融、医疗等行业用户的众多核心业务系统来说是无法容忍的,而消除静默错误带来的风险就需要依靠端到端数据保护技术。
端到端数据保护的关键就在于PI(Protection Information)作为元数据时的传输与校验,元数据有DIF和DIX两种方式,经过T10组织的相关工作已经实现了标准化。简单来说,DIF即元数据与用户数据(LBA Data)连续存放;而 DIX格式则是元数据与用户数据单独存放;根据应用场景的需求,设计解决方案时可以适配DIX或DIF格式。(本文中提到的元数据主要指端到端数据保护的PI信息。)
DIF和DIX元数据原理图
DIF/DIX等几个基本概念解释到这,下如何判断一块盘是否具有端到端数据保护功能。本文的测试环境如下:
NVMe SSD设备:PBlaze5 D926 NVMe SSD(3.2TB)
NVMe version: 1.2
操作系统:Centos 7.4
Kernel:4.19.44(为了确保端到端数据保护功能的稳定运行,建议使用高版本的长期支持版Kernel。)
NVMe 命令工具:nvmecli 1.10.1
对PBlaze5 D926执行Identify Namespace 命令,与端到端数据保护有关的结果摘选如下:
可以看到,PBlaze5 D926支持DIX和DIF,并且支持Type1/2/3三种type(与PI的格式有关,后文会对三种type做解释)。
PBlaze5 920系列端到端数据保护技术一个重要的特点就是支持多种sector size和pi的组合,也就是VSS技术。同样是刚才的Identify Namespace 命令,我们查找这块PBlaze5 D926支持的format格式。
# nvme id-ns /dev/nvme0n1 -H
LBA Format 0 : Metadata Size: 0 bytes - Data Size: 512 bytes - Relative Performance: 0x2 Good (in use)
LBA Format 1 : Metadata Size: 0 bytes - Data Size: 4096 bytes - Relative Performance: 0 Best
LBA Format 2 : Metadata Size: 8 bytes - Data Size: 512 bytes - Relative Performance: 0x2 Good
LBA Format 3 : Metadata Size: 8 bytes - Data Size: 4096 bytes - Relative Performance: 0 Best
LBA Format 4 : Metadata Size: 64 bytes - Data Size: 4096 bytes - Relative Performance: 0x2 Good
从上面的结果可以看出,PBlaze5 D926支持512 Bytes和4096 Bytes两种sector size的格式化,并且两种sector size还均支持带8 Bytes的元数据,并且还支持4096 +64 Bytes的格式化方式,这就是VSS技术的灵活之处。
有了这些知识,我们就可以执行nvme format命令。他的命令帮助如下:
在选项里,与端到端保护相关的是-l(指定format的格式)、--p(指定pi格式)、--p(指定PI在元数据中的位置)、--m(1为DIF,0为DIX)。此外,用户还可以根据需求设置—reset和—force等参数。
# nvme format /dev/nvme0n1 -n 1 -l 2 -i 1 -m 1 -p 1
再回到文章开始的这条format命令。他的意思是将/dev/nvme0n1格式化,sector size为512+8B(8B为PI信息大小),并且采用DIF标准,将8字节大小PI信息放在元数据开头,元数据位于数据LBA的结尾部分。
再次执行对namespace的状态进行检查,并找到flbas 的结果:
# nvme id-ns /dev/nvme0n1 -H
flbas : 0x12
[4:4] : 0x1 Metadata Transferred at End of Data LBA
[3:0] : 0x2 Current LBA Format Selected
至此,这块PBlaze5 D926端到端数据保护功能已经打开。用户无需关心PI信息如何进行存放或者传输的问题。而下一篇文章我们将通过nvme write命令,来解读如何验证端到端数据保护,并走进PI,了解其type1/2/3三种形式的异同。
在现实应用中,存储阵列在端到端数据保护领域有长期的积累,其对数据可靠性要求级别非常高,因此是NVMe SSD端到端数据保护的一个重要应用方向,此外PBlaze5 系列的双端口等功能同样为打造高可靠、高可用闪存阵列提供了有力支持。在Memblaze与宏杉科技为代表的存储厂商长期合作中,双方已经在闪存阵列领域有了诸多突破。
在进行读写操作之前, 我们先要熟悉一下 Protection Information的定义
在列举命令之前需要简要介绍一下Protection Info的格式:
PI保护信息的数据结构
可以看到每个8bytes的PI都会包括由16 比特 guard tag(用户数据的CRC校验信息),16比特application tag(应用指定tag)和32比特reference tag(检测数据写入正确的LBA地址)组成。
端到端数据保护中的Type1/2/3就代表了不同的reference tag设置和PI检查方式。
基本知识介绍完毕。接下来就让Host发笔写数据给这块PBlaze5 D926 NVMe SSD。
#dd if=/dev/urandom of=data_rand.bin bs=512 count=1 oflag=direct
# nvme write /dev/nvme0n1 -s 0x12345678 -z 512 -y 8 -d data_rand.bin --prinfo=0xf --ref-tag=0x12345678
write: Success
上图中第一条命令先生成了一个512Bytes的实验数据,并在由第二条write命令写入到NVMe SSD中。在这条命令中,-s指明了数据起始的LBA,-z是数据量,-y为元数据大小。倒数第二个--prinfo既是Protection Information Field 的意思,其包含PRACT和PRCHK两个参数,分别有如下定义:
PRACT(指明了PI信息生成的机制)
=1时, controller生成PI并将其写入NAND
=0时, controller获取上层应用下发的PI信息,将检查PI信息并写入NAND
PRCHK(指明了控制器收到包时检查的PI信息)
Bit2=1,SSD在收到packet时,检查CRC
Bit1=1,SSD在收到packet时,检查App Tag
Bit0=1,SSD在收到packet时,检查Reference Tagca
这条命令里我们设置了PRINFO为0xf(即所有bit均为1),并且指定了一个ref-tag(0x12345678) 。NVMe SSD控制器在接到命令之后为数据生成PI并整合命令中ref-tag的值,存进NAND。不指定ref-tag,那么控制器会生成完整的PI信息,存进NAND。这个过程示意如下:
相应的,我们将刚写进SSD的数据读出来。
nvme read /dev/nvme0n1 -s 0x12345678 -z 512 -y 8 -d data_meta_read_7.bin --prinfo=0x7 --ref-tag=0x12345678
同样,我们在命令中也看到了prinfo参数,这里的PRINFO同样包含PRACT和PRCHK,其作用解释如下:
PRACT(指明读数据时控制器是否返回PI信息)
=1时, SSD controller不向host返回PI信息;只返回data block
=0时, SSD controller;检查PI信息, 向host返回PI信息以及data block
PRCHK(指明控制器校验的PI信息)
Bit2=1,SSD在收到packet时,检查CRC
Bit1=1,SSD在收到packet时,检查App Tag
Bit0=1,SSD在收到packet时,检查Reference Tag
这条命令可以解释为,我们从起始LBA为0x12345678开始读512Bytes数据和8Bytes元数据,并记录进data_meta_read_7.bin文件中。在此过程检查CRC、APP tag和Reference Tag三个PI信息,并将PI信息和数据一并返回给host。整个过程如下图:
读命令中ref-tag=0x12345678,与上文写命令中ref-tag相等,否则会报出end-to-end reference tag check failure。
读者朋友们如果有兴趣,可以尝试,在read 命令中去掉 ref-tag; 或者将ref-tag修改为其他值;看一下返回结果的变化。
我们展示了一组数据如何通过nvme write命令从host下发到SSD,最终存进NAND;又如何通过nvme read命令将数据校验后正确读出。需要指出的是为了便于理解,我们限制了很多实验条件,事实上不同的PRINFO、不同的应用及系统环境都会有相应的规范。需要深入定制的用户可以联系我们的工程师进行进一步沟通!
参考阅读:
NVMe Specification Revision 1.2a
蛋蛋读剩的NVMe之2:E2E Data Protection