任何新技術(shù)的出現(xiàn)都是為了解決當(dāng)前情況存在的問(wèn)題。NVMe的出現(xiàn)也是為了解決當(dāng)前存在的問(wèn)題。這個(gè)問(wèn)題就是日益快速增長(zhǎng)的存儲(chǔ)介質(zhì)性能與傳輸通道性能太差之間的矛盾。基于SSD的存儲(chǔ)設(shè)備性能都要上天了,但SAS和SATA接口的性能卻沒(méi)有本質(zhì)的提升。
目前基于SCSI協(xié)議的SAS和SATA只能是單個(gè)隊(duì)列而且每個(gè)隊(duì)列的深度也比較低,分別是254和32的隊(duì)列深度。而NVMe協(xié)議設(shè)計(jì)之初就考慮了該問(wèn)題,它的***隊(duì)列數(shù)量可以是64K(65535個(gè)命令隊(duì)列和1個(gè)管理隊(duì)列),而每個(gè)隊(duì)列的深度可以高達(dá)64K。與SCSI協(xié)議相比,就好比一個(gè)鄉(xiāng)村的羊腸小路和一個(gè)雙向八車(chē)道的高速公路的差別。
圖1 美麗的鄉(xiāng)村下路和京港澳高速
NVMe基本原理
為了便于理解主機(jī)和NVMe設(shè)備的關(guān)系,我們這里簡(jiǎn)化NVMe設(shè)備的內(nèi)部結(jié)構(gòu)。如圖2所示為NVMe白皮書(shū)中的配圖,這里主機(jī)稱(chēng)為Host,而NVMe設(shè)備稱(chēng)為Controller(控制器)。主機(jī)和控制器之間通過(guò)共享內(nèi)存的隊(duì)列實(shí)現(xiàn)交互。
圖2 NVMe多隊(duì)列示意圖
NVMe的隊(duì)列分為2種,其中一種是用于管理的隊(duì)列,稱(chēng)為Admin Queue(管理隊(duì)列),僅有一個(gè),另外一種是命令隊(duì)列(Command Queue),最多可以有65535個(gè)。其中命令隊(duì)列的數(shù)量和模式都是通過(guò)管理隊(duì)列來(lái)設(shè)置的。其中每一個(gè)隊(duì)列實(shí)際上是一個(gè)隊(duì)列對(duì),也就是包括兩個(gè)隊(duì)列,分別是提交隊(duì)列(Submission Queue)和完成隊(duì)列(Completion Queue)。提交隊(duì)列用于主機(jī)端向NVMe設(shè)備發(fā)送NVMe命令,而完成隊(duì)列則用于NVMe設(shè)備向主機(jī)反饋命令執(zhí)行情況。實(shí)際上NVMe還有另外一種模式,就是多個(gè)提交隊(duì)列共享同一個(gè)完成隊(duì)列的情況,本文暫時(shí)不做介紹。
NVMe隊(duì)列及命令的處理流程
上文我們知道NVMe是通過(guò)隊(duì)列傳遞控制命令和命令等內(nèi)容的,那么這里的隊(duì)列實(shí)體到底是什么呢?其實(shí)這里提交隊(duì)列和完成隊(duì)列就是內(nèi)存的一個(gè)區(qū)域。在數(shù)據(jù)結(jié)構(gòu)原理上這里的隊(duì)列其實(shí)是一個(gè)環(huán)形緩沖區(qū),如圖3所示。
圖3 環(huán)形緩沖區(qū)
NVMe通過(guò)一種門(mén)鈴機(jī)制(Doorbell)來(lái)告知控制器命令隊(duì)列是否有新數(shù)請(qǐng)求/命令。也就是說(shuō)每個(gè)隊(duì)列都有一個(gè)門(mén)鈴指針。對(duì)于發(fā)送隊(duì)列來(lái)說(shuō),這個(gè)指針表示的是發(fā)送隊(duì)列的尾指針。主機(jī)端將數(shù)據(jù)寫(xiě)入到發(fā)送隊(duì)列后,更新映射到位于設(shè)備寄存器空間中的門(mén)鈴的尾指針。此時(shí),在控制器端就知道有新的請(qǐng)求/命令到來(lái),接下來(lái)就可以進(jìn)行對(duì)其進(jìn)行處理。
當(dāng)控制器完成一個(gè)NVMe請(qǐng)求時(shí),通過(guò)完成隊(duì)列來(lái)把完成的結(jié)果告知主機(jī)端。與發(fā)送隊(duì)列不同,完成隊(duì)列是通過(guò)中斷機(jī)制(可以是INTx,MSI或MSIx)告訴主機(jī)端。如圖4是一個(gè)命令的完整處理流程。
圖4 命令處理完整流程
NVMe的命令格式
前面我們介紹了命令的發(fā)送和處理流程,接下來(lái)我們看看NVMe的命令長(zhǎng)什么樣。如圖5是NMVe命令的具體格式,如果大家了解TCP/IP協(xié)議或者SCSI協(xié)議,那么理解本圖將相當(dāng)容易。在圖4中每一行為8個(gè)字節(jié),命令大小總共為64字節(jié)。
圖5 NVMe的命令格式
在這個(gè)命令格式中有幾個(gè)字段本身是比較復(fù)雜的,限于篇幅,且不打算讓大家看完本文后頭疼,本文不打算介紹所有細(xì)節(jié)。本文簡(jiǎn)單的介紹一下該命令格式的幾個(gè)關(guān)鍵字段。其中Command Identifier標(biāo)識(shí)一個(gè)具體的命令。Namespace Identifier則表示命令發(fā)送到那個(gè)命名空間。Data Pointer 1 和Data Pointer 2則用于標(biāo)識(shí)數(shù)據(jù)的具體位置。
這里有兩點(diǎn)需要說(shuō)明:
NVMe的一個(gè)控制器下面可以有多個(gè)命名空間(Namespace),通過(guò)Namespace ID來(lái)標(biāo)識(shí)的。
命令與數(shù)據(jù)是分離的,并不像TCP那樣數(shù)據(jù)在命令后面。
我們這里重點(diǎn)介紹一下Command Identifier,該字段占用4個(gè)字節(jié)的空間。雖然僅有4個(gè)字節(jié),但有分為3大部分,6小部分,具體如圖6所示。
圖6 命令標(biāo)識(shí)格式
我們以從低位到高位的順序分別介紹一下各個(gè)字段的含義:
OPC: 全稱(chēng)為Opcode,也就是被執(zhí)行命令的操作碼。具體來(lái)說(shuō)就是想讓控制器干什么,比如讀數(shù)據(jù)、寫(xiě)數(shù)據(jù)或者刷寫(xiě)等。
圖7 OPC定義
FUSE: 全稱(chēng)為Fused Operation, 用于標(biāo)識(shí)該命令是普通命令還是復(fù)合命令。如圖8是白皮書(shū)對(duì)該字段的說(shuō)明。
圖8 FUSE的定義
PSDT: 全稱(chēng)為PRP or SGL for Data Transfer,這個(gè)用于說(shuō)明存儲(chǔ)數(shù)據(jù)的內(nèi)存的組織形式。
NVMe的性能
***我們看一下NVMe與SAS和SATA存儲(chǔ)設(shè)備的性能對(duì)比。為了避免廣告嫌疑,本文就布局圖說(shuō)明設(shè)備的廠商和類(lèi)型了。
圖9 性能對(duì)比
通過(guò)上圖可以清楚的看到SAS和SATA設(shè)備與NVMe設(shè)備的性能差異,特別是對(duì)于讀操作,NVMe有絕對(duì)的性能優(yōu)勢(shì)。
來(lái)源:itworld123 (SunnyZhang)
評(píng)論