NVMe端到端数据保护功能

Host与SSD之间数据传输的最小单位是逻辑块(Logcal Block LB),每个逻辑块的大小可以是512/1024/2048/4096字节等,Host在格式化SSD时便确定了逻辑块的大小。数据从Host到NVM 闪存,首先要经过PCIe传输到SSD的控制器,然后控制器把数据写入闪存。反过来,Host想从闪存读取数据,首先SSD控制器从闪存上获得数据,然后经过PCIe将数据传给Host。

1.1.png

Host与SSD之间传输数据的时候由于信道噪声的存在,数据可能出错。SSD内部控制器与闪存之间的数据传输也可能出错,为了保证Host端到闪存端数据传输安全,NVMe提供了一个端到端数据保护。除了逻辑块数据本身,NVMe还允许每个逻辑块带个助理,叫做元数据(Meta Data)。这个助理的职责,NVMe虽然没有明确的要求,但如果数据需要保护,NVMe要求这个助理必须能充当保镖的角色。我们只关心元数据是如何保护逻辑块数据的。NVMe要求每个逻辑块数据的元数据带有以下信息:

1.1.png

其中的”Guard”是16比特的CRC (Cyclic Redundancy Check),它是逻辑块数据算出来的;”Application Tag”和”Reference Tag”包含该数据块的逻辑地址(LBA)等信息。CRC校验能够检测出数据是否有错,后者则是保证数据不会出现张冠李戴的问题,比如我LBA X使用了LBA Y的数据,这种情况往往是SSD固件Bug导致的。Anyway,NVMe能帮你发现这个问题。佩了元数据的的逻辑块看起来就是下面这个样子(以512字节的数据块为例):

1.1.png

并不是所有时刻都需要带上元数据,因为PCIe可以通过TLP上的Digest域提供数据保护,这个Digest是可选的,如果被使能,则NVMe层没有必要进行额外的数据保护。但是Digest不能解决张冠李戴的问题。有的时候需要把PI也写入闪存,这样SSD控制器从闪存读取数据的时候就能计算是否出错。如果PCIe已经使能了Digest提供了数据保护,则NVMe只需要在SSD控制器和闪存之间加上PI提供数据保护。

数据端到端保护是NVMe的一个特色,其本质就是在数据块当中加入CRC和数据块对应的LBA等冗余信息,SSD Controller或者Host端利用这个这些信息进行数据校验,然后根据校验结果执行相应的操作。加入这些检错信息的好处是能让Host与SSD Controller及时发现数据错误,副作用就是:

  • 每个数据块需要额外的至少8字节的数据保护信息,有效带宽减少:数据块大小越小,带宽影响越大
  • SSD Controller需要做数据校验,影响性能。

NVMe Namespace

1.1.png 1.1.png

上图中红圈圈起来的是一个NVMe子系统,通常来说就是SSD。一个NVMe SSD主要由SSD Controller,闪存空间和PCIe接口组成。如果把闪存空间划分成若干个独立的逻辑空间,每个空间逻辑块地址(LBA)范围是0到N-1 (N是逻辑空间大小),这样划分出来的每一个逻辑空间我们就叫做NS。每个NS都有一个名称与ID,如同每个人都有名字和身份证号码,ID是独一无二的,系统就是通过 NS的ID来区分不同的NS。如上图例子,整个闪存空间划分成2个NS,名字分别是NS A和NS B,对应的NS ID分别是1和2。如果NS A大小是M (以逻辑块大小为单位),NS B大小是N,则他们的逻辑地址空间分别是0到M-1和0到N-1。Host读写SSD,都是要在命令中指定读写的是哪个NS中的逻辑块。原因很简单,如果不指定NS,对同一个LBA来说,假设就是LBA 0,SSD根本就不知道去读或者写哪里,因为有两个逻辑空间,每个逻辑空间都有LBA 0。

一个NVMe命令一共64字节,其中第4到第7个Byte指定了要访问的NS。

1.1.png 1.1.png

对每个NS来说,都有一个4KB大小的数据结构来描述它。该数据结构描述了该NS的大小,整个空间已经写了多少,每个LBA的大小,以及端到端数据保护相关设置,该NS是否属于某个Controller还是几个Controller可以共享,等等。NS由Host创建和管理,每个创建好的NS,从Host操作系统角度看来,就是一个独立的磁盘,用户可在每个NS做分区等操作。下图中,整个闪存空间划分成两个NS,NS A和NS B,操作系统看到两个完全独立的磁盘。NS更多的是应用在企业级,可以根据客户不同需求创建不同特征的NS,也就是在一个SSD上创建出若干个不同功能特征的磁盘(NS)供不同客户使用。

1.1.png

NS的另一个重要的使用场合是SR-IOV(Single root-I/O Virtualization)

SR-IOV技术允许虚拟机之间高效共享PCIe设备,并且它是在硬件中实现的,可以获得能够与本机性能媲美的I/O 性能。单个I/O 资源(单个SSD)可由许多虚拟机共享。共享的设备将提供专用的资源,并且还使用共享的通用资源。这样,每个虚拟机都可访问唯一的资源。

1.1.png

上图所示,该SSD作为PCIe的一个Endpoint,实现了一个物理功能PF,还有四个虚拟功能关联该PF。每个VF都有自己的独享NS也有共享NS。这个功能使得虚拟功能可以共享物理设备且在没有CPU和虚拟机管理软件开销的情况下执行IO。

  • 对一个NVMe子系统来说,除了包含若干个NS,还可以由若干个 SSD Controller。注意,这里不是说一个SSD Controller有多个CPU,而是说一个SSD有几个实现了NVMe功能的Controller。

    1.1.png

    如上图例子,一个NVMe子系统包含了两个Controller,分别实现不同功能(也可以是相同功能)。整个闪存空间分成3个NS,其中NS A由Controller 0(左边)独享,NS C由Controller 1(右边)独享,而NS B是两者共享。独享的意思是说只有与之关联的Controller才能访问该NS,别的Controller是不能对之访问的,上图中Controller 0是不能对NS C进行读写操作的,同样,Controller 1也不能访问 NS A;共享的意思是说,该NS(这里是NS B)是可以被两个Controller共同 访问的。对共享NS,由于几个Controller都可以对它进行访问,所以要求每个Controller对该NS的访问都是原子操作,从而避免同步问题。

  • 事实上,一个NVMe子系统,除了可以有若干个NS,除了可以有若干个Controller,还可以有若干个PCIe接口。下图是两个PCIe接口连着一个主机的情况:

    1.1.png

    1.1.png

    优点:一方面,Host访问SSD,可以双管齐下,性能可能更好点。不过对访问NS B来说,同一时刻只能被一个Controller访问,双管齐下又如何。考虑到还可以同时操作NS A 和 NS C,性能或多或少的有所提升。更重要的是,这种双接口冗余设计,可以提升系统可靠性。假设 PCIe A接口出现问题,这个时候Host可以通过 PCIe B无缝衔接,继续对NS B进行访问。当然了,NS A是无法访问了。

    1.1.png

    1.1.png

    每个Port可连接两个独立Host,Host有两个独立的数据通道(Data Path)对闪存空间进行访问,如果其中一个数据通道发生故障,OCZ的Host热交换(Hot-swap )技术能让另外一个Host无缝低延时的接管任务。有些应用,比如银行金融系统、在线交易处理(OnLine Transaction Processing,OLTP)、在线分析处理(OnLine Analytical Processing,OLAP)、高性能计算(High Performance Computing ,HPC),大数据等,对系统可靠性和实时性要求非常高,带有Dual Port的SSD就能派上用场了。

    多NS,多Controller,多PCIe接口,给NVMe SSD开发者,以及存储架构师很大的发挥空间。给不同的NS配置不同的数据保护机制,或者虚拟化,或者使用冗余容错提高系统可靠性,抑或别的设计,NVMe提供了这些基础设施,怎么玩就看你的想象力了。