編者按
軟件和硬件,既相互依存又需要某種程度上的相互獨立。通過軟件和硬件之間的接口把兩者連接在一起。軟硬件接口,有很多含義:比如指令集是CPU軟件和硬件之間的接口;比如一些硬件模塊(包括IO接口模塊、GPU、各種加速引擎等)暴露出來的可讀寫寄存器,則為控制接口;再比如,CPU和GPU或其他硬件模塊之間通過DMA進(jìn)行數(shù)據(jù)交互的(軟硬件間的)數(shù)據(jù)傳輸接口。 軟硬件接口,是個非常龐大的命題。本文是《軟硬件融合》圖書內(nèi)容的節(jié)選,聚焦在軟件和硬件之間的數(shù)據(jù)交互接口。
軟件和硬件之間數(shù)據(jù)交互接口
我們在計算機的基礎(chǔ)課程里一般都學(xué)過IO交互的四種模式:寄存器模式、中斷模式、DMA模式和通道模式。隨著計算機技術(shù)的發(fā)展,除了IO設(shè)備,還有很多獨立的硬件組件通過各種類型總線跟CPU連接在一起。接口已經(jīng)不僅僅是用于IO數(shù)據(jù)傳輸場景,也用于軟件(運行于CPU的程序)和其他硬件之間的數(shù)據(jù)交互場景。 注:本文用“軟硬件接口”特指軟件和硬件之間數(shù)據(jù)交互的接口。
1 軟硬件接口定義
傳統(tǒng)的非硬件緩存一致性總線,是需要軟件驅(qū)動顯式的控制設(shè)備來進(jìn)行數(shù)據(jù)交互的。通過梳理軟硬件接口的演進(jìn),逐步給出軟硬件接口的定義。 a. 軟硬件接口演進(jìn)
(a) CPU輪詢? ? ? ? ? ? ? ? ? ?(b) CPU中斷???? ?? ? ? ???? ? (c) DMA方式
(d) 共享隊列??? ? ? ???? ???
(e) 用戶態(tài)輪詢???? ?? ? ? ??? ?
(f) 多隊列 圖1 軟硬件接口的演進(jìn) 軟硬件接口是在IO接口基礎(chǔ)上的擴展,如圖1,我們結(jié)合IO交互的四種模式,重新梳理一下軟硬件接口的演進(jìn):
第一階段,使用軟件輪詢硬件狀態(tài)。如圖1(a),最開始是通過軟件輪詢,這時候軟件和硬件的交互非常簡單。發(fā)送的時候,軟件會定期的去查詢硬件的狀態(tài),當(dāng)發(fā)送緩沖為空的時候,就把數(shù)據(jù)寫入到硬件的緩存寄存器;接收的時候,軟件會定期的查詢硬件的狀態(tài),當(dāng)接收緩沖區(qū)有數(shù)據(jù)的時候,就把數(shù)據(jù)讀取到軟件。
第二階段,使用中斷模式。如圖1(b),隨著CPU的性能快速提升,統(tǒng)計發(fā)現(xiàn),輪詢的失敗次數(shù)很高,大量的CPU時間被浪費在硬件狀態(tài)查詢而不是數(shù)據(jù)傳輸,因此引入中斷模式。只有當(dāng)發(fā)送緩沖存在空閑區(qū)域可以讓軟件存放一定量待發(fā)送數(shù)據(jù)的時候,或者接收緩沖已經(jīng)有一定量數(shù)據(jù)待軟件接收的時候,硬件會發(fā)起中斷,CPU收到中斷后進(jìn)入中斷服務(wù)程序,在中斷服務(wù)程序里處理數(shù)據(jù)的發(fā)送和接收。
第三階段,引入DMA。如圖1(c),前面的兩種情況下,都需要CPU來完成數(shù)據(jù)的傳輸,依然會有大量的CPU消耗。因此引入了專用的數(shù)據(jù)搬運模塊DMA來完成CPU和硬件之間的數(shù)據(jù)傳輸,某種程度上,DMA可以看做是用于代替CPU進(jìn)行數(shù)據(jù)搬運的加速器。發(fā)送的時候,當(dāng)數(shù)據(jù)在CPU內(nèi)存準(zhǔn)備好,CPU告訴DMA源地址和數(shù)據(jù)的大小,DMA收到這些信息后主動把數(shù)據(jù)從CPU內(nèi)存搬到硬件內(nèi)部。同樣的,接收的時候,CPU開辟好一片內(nèi)存空間并告知DMA目標(biāo)地址和空間的長度,DMA負(fù)責(zé)把硬件內(nèi)部的數(shù)據(jù)搬運到CPU內(nèi)存。
第四階段,專門的共享隊列。如圖1(d),引入了DMA之后,如果只有一片空間用于軟件和硬件之間的數(shù)據(jù)交換,則軟件和硬件之間的數(shù)據(jù)交換則是同步的。例如在接收的時候,當(dāng)DMA把數(shù)據(jù)搬運到CPU內(nèi)存之后,CPU需要馬上進(jìn)行處理并釋放內(nèi)存,CPU處理的時候DMA則只能停止工作。后來引入了乒乓緩沖的機制,當(dāng)一個內(nèi)存緩沖區(qū)用于DMA傳輸數(shù)據(jù)的時候,另一個緩沖區(qū)的數(shù)據(jù)由CPU進(jìn)行處理,實現(xiàn)DMA傳輸和CPU處理的并行。更進(jìn)一步的,演變成更多緩沖區(qū)組成的循環(huán)緩沖隊列。這樣,CPU的數(shù)據(jù)處理和DMA的數(shù)據(jù)傳輸則完全異步的完成,并且CPU對數(shù)據(jù)的處理以及DMA對數(shù)據(jù)的搬運都可以批量操作完成后,再同步狀態(tài)信息給對方。
第五階段,用戶態(tài)的軟件輪詢共享隊列驅(qū)動。如圖1(e),進(jìn)一步的,隨著帶寬和內(nèi)存的增加,導(dǎo)致數(shù)據(jù)頻繁的在用戶態(tài)應(yīng)用程序、內(nèi)核的堆棧、驅(qū)動以及硬件之間交互,并且緩沖區(qū)也越來越大,這些都不可避免的增加系統(tǒng)消耗,并且?guī)砀嗟难舆t;而且,數(shù)據(jù)交互頻繁,導(dǎo)致的中斷的開銷也是非常龐大的。因此,通過用戶態(tài)的PMD(Polling Mode Driver,輪詢模式驅(qū)動)可以高效的在硬件和用戶態(tài)的應(yīng)用程序直接傳遞數(shù)據(jù),不需要中斷,完全繞開內(nèi)核,以此來提升性能和降低延遲。
第六階段,支持多隊列。如圖1(f),隨著硬件設(shè)計規(guī)模擴大,硬件資源越來越多,在單個設(shè)備里,可以通過多隊列的支持,來提高并行性。驅(qū)動也需要加入對多隊列的支持,這樣我們甚至可以為每個應(yīng)用程序配置專用的隊列或隊列組,通過多隊列的并行性來提升性能和應(yīng)用數(shù)據(jù)的安全性。
說明:本小節(jié)所講的內(nèi)容,主要是基于傳統(tǒng)的非緩存一致性總線的數(shù)據(jù)交互演進(jìn)。隨著跨芯片的緩存數(shù)據(jù)一致性總線開始流行,通過硬件完成數(shù)據(jù)交互,在提升性能的同時,也簡化了軟件設(shè)計。 b. 軟硬件接口的組成部分 粗略的說,軟硬件接口是由驅(qū)動(Driver)和設(shè)備(Device)組成,驅(qū)動和設(shè)備的交互也即軟件和硬件的交互。更確切一些的說,軟硬件接口包括交互的驅(qū)動軟件、硬件設(shè)備的接口部分邏輯,也包括內(nèi)存中的共享隊列,還包括傳輸控制和數(shù)據(jù)信息的總線。
圖2軟硬件接口硬件架構(gòu)示意模型 如圖2,是軟硬件接口硬件架構(gòu)的示意模型。軟硬件接口的組件詳細(xì)介紹如下:
驅(qū)動軟件。驅(qū)動是提供一定的接口API,讓上層的軟件能夠更加方便的與硬件交互。驅(qū)動負(fù)責(zé)硬件設(shè)備控制面的配置、運行控制以及設(shè)備數(shù)據(jù)面的數(shù)據(jù)傳輸控制等。驅(qū)動屏蔽硬件的接口細(xì)節(jié),對上層軟件提供標(biāo)準(zhǔn)的API函數(shù)接口。驅(qū)動屏蔽硬件細(xì)節(jié),提供標(biāo)準(zhǔn)API給上層軟件,在單機系統(tǒng)是非常有價值的。通過不同版本的驅(qū)動,既可以屏蔽硬件細(xì)節(jié),又可以跟不同的操作系統(tǒng)平臺兼容。在云計算場景,要求要更嚴(yán)格一些,云場景期望是完全標(biāo)準(zhǔn)的硬件接口。驅(qū)動是代表軟件與硬件交互的接口,但依然是軟件的一部分,在云計算虛擬機驅(qū)動也會遷移到新的環(huán)境,這就要求新的運行環(huán)境和原始環(huán)境一致。也就是說,在IO直通模式下,需要雙方的硬件接口本身就是一致的。
設(shè)備硬件接口子模塊,包括DMA和內(nèi)部緩沖。高速的設(shè)備一般都有專用的DMA,專門負(fù)責(zé)數(shù)據(jù)搬運。驅(qū)動會通知DMA共享隊列狀態(tài)信息,然后DMA會讀取內(nèi)存中的共享隊列描述符,并根據(jù)描述符信息負(fù)責(zé)在CPU內(nèi)存和內(nèi)部緩沖之間搬運數(shù)據(jù)。
共享隊列。特定的跟硬件DMA格式兼容的共享隊列數(shù)據(jù)結(jié)構(gòu),軟件和硬件通過共享隊列交互數(shù)據(jù)。每個共享隊列包括隊列的頭和尾指針、組成隊列的各個描述符項以及每個描述符項所指向的實際的數(shù)據(jù)塊。共享隊列位于軟件側(cè)的CPU內(nèi)存里,由軟件驅(qū)動負(fù)責(zé)管理。
傳輸?shù)目偩€:軟硬件交互可以說是上層功能,需要底層接口總線的承載。例如,在片內(nèi)通常是通過AXI-Lite總線來實現(xiàn)軟件對硬件的寄存器讀寫控制,而數(shù)據(jù)總線則是通過AXI實現(xiàn)硬件DMA對軟件的CPU內(nèi)存的讀寫訪問。芯片間的總線常見的主要是PCIe,通過PCIe的TLP包來承載上層的各種類型的讀寫訪問。
2 生產(chǎn)者消費者模型
生產(chǎn)者消費者問題(Producer-Consumer Problem)是多進(jìn)程同步問題的經(jīng)典案例之一,描述了共享固定大小緩沖區(qū)的兩個進(jìn)程,即所謂的“生產(chǎn)者”和“消費者”,在實際運行時如何處理交互的問題。 如圖3所示,生產(chǎn)者的主要作用是生成一定量的數(shù)據(jù)放到緩沖區(qū)中,然后重復(fù)此過程。與此同時,消費者也在緩沖區(qū)消耗這些數(shù)據(jù)。問題的關(guān)鍵就是要保證生產(chǎn)者不會在緩沖區(qū)滿時加入數(shù)據(jù),消費者不會在緩沖區(qū)中空時消耗數(shù)據(jù)。
圖3 經(jīng)典生產(chǎn)者消費者模型 解決問題的基本辦法是:讓生產(chǎn)者在緩沖區(qū)滿時休眠,等到消費者消耗緩沖區(qū)中的數(shù)據(jù),從而緩沖區(qū)有了空閑區(qū)域的時候,生產(chǎn)者才能被喚醒,開始繼續(xù)往緩沖區(qū)添加數(shù)據(jù);同樣,也需要讓消費者在緩沖區(qū)空時進(jìn)入休眠,等到生產(chǎn)者往緩沖區(qū)添加數(shù)據(jù)之后,再喚醒消費者繼續(xù)消耗數(shù)據(jù)。 a. 進(jìn)程間通信 一個生產(chǎn)者進(jìn)程,一個消費者進(jìn)程,生產(chǎn)者進(jìn)程通過共享緩沖傳遞數(shù)據(jù)給消費者進(jìn)程。如果程序員不夠小心,沒有考慮多進(jìn)程間相互影響的話,很可能寫出下面這段會導(dǎo)致“死鎖”的代碼。
// 該算法使用了兩個系統(tǒng)庫函數(shù):sleep 和 wakeup。 // 調(diào)用 sleep的進(jìn)程會被阻斷,直到有另一個進(jìn)程用wakeup喚醒之。 // 代碼中的itemCount用于記錄緩沖區(qū)中的數(shù)據(jù)項數(shù)。 int?itemCount?=?0; procedure producer() { while (true) { item = produceItem(); if (itemCount == BUFFER_SIZE) { sleep(); } putItemIntoBuffer(item); itemCount = itemCount + 1; if (itemCount == 1) { wakeup(consumer); } } } procedure consumer() { while (true) { if (itemCount == 0) { sleep(); } item = removeItemFromBuffer(); itemCount = itemCount - 1; if (itemCount == BUFFER_SIZE - 1) { wakeup(producer); } consumeItem(item); } }上面代碼中的問題在于它可能導(dǎo)致競爭條件,進(jìn)而引發(fā)死鎖??紤]下面的情形:
消費者進(jìn)程把最后一個itemCount的內(nèi)容讀出來(注意它現(xiàn)在是零),消費者進(jìn)程返回到while的起始處,現(xiàn)在進(jìn)入if塊。
就在調(diào)用sleep之前,OS調(diào)度,決定將CPU時間片讓給生產(chǎn)者進(jìn)程,于是消費者進(jìn)程在執(zhí)行sleep之前就被中斷了,生產(chǎn)者進(jìn)程開始執(zhí)行。
生產(chǎn)者進(jìn)程生產(chǎn)出一項數(shù)據(jù)后將其放入緩沖區(qū),然后在itemCount上加 1;由于緩沖區(qū)在上一步加1之前為空,生產(chǎn)者嘗試喚醒消費者。
遺憾的是,消費者并沒有在休眠,喚醒指令不起作用。當(dāng)消費者恢復(fù)執(zhí)行的時候,執(zhí)行 sleep,一覺不醒(出現(xiàn)這種情況的原因在于,消費者只能被生產(chǎn)者在itemCount為1的情況下喚醒)。
生產(chǎn)者不停地循環(huán)執(zhí)行,直到緩沖區(qū)滿,隨后進(jìn)入休眠。
由于兩個進(jìn)程都進(jìn)入了永遠(yuǎn)的休眠,死鎖情況出現(xiàn)了。因此,該算法是不完善的。我們可以通過引入信號量(Semaphore)的方式來完善這個算法。信號量能夠?qū)崿F(xiàn)對某個特定資源的互斥訪問。
// 該方法使用了兩個信號燈,fillCount和emptyCount; // fillCount用于記錄緩沖區(qū)中存在的數(shù)據(jù)項數(shù)量; // emptyCount用于記錄緩沖區(qū)中空閑空間數(shù)量; // 當(dāng)有新數(shù)據(jù)項被放入緩沖區(qū)時,fillCount增加,emptyCount減少; // 當(dāng)有新數(shù)據(jù)項被取出緩沖區(qū)時,fillCount減少,emptyCount增加; // 如果在生產(chǎn)者嘗試減少emptyCount的時候發(fā)現(xiàn)其值為零,那么生產(chǎn)者就進(jìn)入休眠。 // 等到有數(shù)據(jù)項被消耗,emptyCount增加的時候,生產(chǎn)者才被喚醒。 //?消費者的行為類似。 semaphore fillCount = 0; // 生產(chǎn)的項目 semaphore emptyCount = BUFFER_SIZE; // 剩余空間 procedure producer() { while (true) { item = produceItem(); down(emptyCount); putItemIntoBuffer(item); up(fillCount); } } procedure consumer() { while (true) { down(fillCount); item = removeItemFromBuffer(); up(emptyCount); consumeItem(item); } }b.分布式消息隊列服務(wù) 消息隊列中間件是分布式系統(tǒng)中重要的組件,主要解決應(yīng)用耦合、異步消息、流量削峰等問題。消息(Message)是指在應(yīng)用之間傳送的數(shù)據(jù),消息可以非常簡單,比如只包含文本字符串,也可以更復(fù)雜,可能包含嵌入對象。消息隊列(Message Queue)是一種應(yīng)用間的通信方式,消息發(fā)送后可以立即返回,有消息系統(tǒng)來確保信息的可靠傳遞,消息發(fā)布者只管把消息發(fā)布到MQ中而不管誰來取,消息使用者只管從MQ中取消息而不管誰發(fā)布的,這樣發(fā)布者和使用者都不用知道對方的存在。 如圖4,消息隊列一般由三部分組成:
Producer:消息生產(chǎn)者,負(fù)責(zé)產(chǎn)生和發(fā)送消息到 Broker。
Broker:消息處理中心。負(fù)責(zé)消息存儲、確認(rèn)、重試等,一般其中會包含多個Queue。
Consumer:消息消費者,負(fù)責(zé)從 Broker 中獲取消息,并進(jìn)行相應(yīng)處理。
圖4 消息隊列模型 消息隊列具有如下特性:
異步性。將耗時的同步操作,通過發(fā)送消息的方式,進(jìn)行了異步化處理。減少了同步等待的時間。
松耦合。消息隊列減少了服務(wù)之間的耦合性,不同的服務(wù)可以通過消息隊列進(jìn)行通信,而不用關(guān)心彼此的實現(xiàn)細(xì)節(jié),只要定義好消息的格式就行。
分布式。通過對消費者的橫向擴展,降低了消息隊列阻塞的風(fēng)險,以及單個消費者產(chǎn)生單點故障的可能性(當(dāng)然消息隊列本身也可以做成分布式集群)。
可靠性。消息隊列一般會把接收到的消息存儲到本地硬盤上(當(dāng)消息被處理完之后,存儲信息根據(jù)不同的消息隊列實現(xiàn),有可能將其刪除),這樣即使應(yīng)用掛掉或者消息隊列本身掛掉,消息也能夠重新加載。
互聯(lián)網(wǎng)場景使用較多的消息隊列有ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ等。 c. 驅(qū)動和設(shè)備通信 NIC(Network Interface Adapter,網(wǎng)絡(luò)接口卡)是典型的IO設(shè)備,網(wǎng)絡(luò)數(shù)據(jù)包的傳輸有發(fā)送Tx和接收Rx兩個方向。通過貢獻(xiàn)的Tx Queue和Rx Queue來交互數(shù)據(jù)傳輸。我們以網(wǎng)絡(luò)Tx的傳輸為例,介紹基于生產(chǎn)者消費者模型的驅(qū)動和設(shè)備數(shù)據(jù)交互。 如圖5,給出了網(wǎng)絡(luò)包處理Tx發(fā)送的基本原理示意圖(Rx接收跟Tx發(fā)送類似,控制流程一致,數(shù)據(jù)方向相反)。可以看到,在Tx的時候,驅(qū)動是生產(chǎn)者,設(shè)備是消費者,他們通過內(nèi)存中共享的環(huán)形隊列傳輸數(shù)據(jù)。一般在環(huán)形隊列中的是用于描述數(shù)據(jù)的描述符,通過指針指向?qū)嶋H的數(shù)據(jù)塊。當(dāng)上層應(yīng)用通過驅(qū)動把數(shù)據(jù)寫到環(huán)形隊列以后,驅(qū)動會把環(huán)形隊列相關(guān)的狀態(tài)信息告知設(shè)備端。設(shè)備端接收到信息后DMA開始工作,首先讀取環(huán)形隊列中的相應(yīng)描述符,然后通過描述符信息搬運實際的數(shù)據(jù)塊到硬件內(nèi)部。搬運完成后硬件通過中斷告知驅(qū)動,然后驅(qū)動會釋放此塊緩沖。
圖5 網(wǎng)絡(luò)驅(qū)動和設(shè)備通信示意圖
3 用戶態(tài)輪詢驅(qū)動:DPDK和SPDK
DPDK和SPDK是當(dāng)前主流的開源高速接口框架,核心的技術(shù)是用戶態(tài)的輪詢驅(qū)動。DPDK/SPDK支持兩個核心的設(shè)備類型:DPDK聚焦高性能網(wǎng)絡(luò)處理,SPDK聚焦高性能存儲處理。 a. DPDK介紹
DPDK(Data Plane Development Kit,數(shù)據(jù)平面開發(fā)套件)是在用戶態(tài)中運行的一組軟件庫和驅(qū)動程序,可加速在CPU架構(gòu)上運行的數(shù)據(jù)包處理工作負(fù)載。DPDK由英特爾大約在2010年創(chuàng)建,現(xiàn)在作為Linux基金會下的一個開源項目提供,在拓展通用CPU的應(yīng)用方面發(fā)揮了重要作用。
?
? |
? | ? |
? | |
(a) 基于Linux內(nèi)核的包處理 | (b) 基于DPDK的包處理 |
圖6 基于DPDK的包處理 如圖6(a),傳統(tǒng)Linux網(wǎng)絡(luò)驅(qū)動存在如下一些問題:
中斷開銷大,大量數(shù)據(jù)傳輸會頻繁觸發(fā)中斷,中斷開銷系統(tǒng)無法承受;
數(shù)據(jù)包從內(nèi)核緩沖區(qū)拷貝到用戶緩沖區(qū),帶來系統(tǒng)調(diào)用和數(shù)據(jù)包復(fù)制的開銷;
對于很多網(wǎng)絡(luò)功能來說,TCP/IP協(xié)議并非數(shù)據(jù)轉(zhuǎn)發(fā)必需;
操作系統(tǒng)調(diào)度帶來的緩存替換也會對性能產(chǎn)生負(fù)面影響。
如圖6(b),DPDK最核心的功能是提供了用戶態(tài)的輪詢模式驅(qū)動,為了加速網(wǎng)絡(luò)IO,DPDK允許傳入的網(wǎng)絡(luò)數(shù)據(jù)包直通到用戶空間而沒有內(nèi)存復(fù)制的開銷,不需要用戶空間和內(nèi)核空間切換時的上下文處理。DPDK可在高吞吐量和低延遲敏感的場景加速特定的網(wǎng)絡(luò)功能,如無線核心、無線訪問、有線基礎(chǔ)設(shè)施、路由器、負(fù)載均衡器、防火墻、視頻流、VoIP等。DPDK所使用的優(yōu)化技術(shù)主要有:
用戶態(tài)驅(qū)動,減少內(nèi)核態(tài)用戶態(tài)切換開銷,減少緩沖區(qū)拷貝;
輪詢模式驅(qū)動(PMD, Polling Mode Driver),不需要中斷,沒有中斷開銷,并且對隊列及數(shù)據(jù)及時處理,降低延遲;
固定處理器核,減少線程切換的開銷,減少緩存失效,同時要考慮NUMA特性,確保內(nèi)存和處理器核在同一個NUMA域中;
大頁機制,減少TLB未命中幾率;
非鎖定的同步,避免等待;
內(nèi)存對齊和緩存對齊,有利于內(nèi)存到緩存的加載效率;
DDIO機制,從IO設(shè)備把數(shù)據(jù)直接送到L3緩存,而不是送到內(nèi)存。
b. SPDK介紹 在數(shù)據(jù)中心中,固態(tài)存儲介質(zhì)正在逐漸替換機械HDD,NVMe在性能、功耗和機架密度方面具有明顯的優(yōu)勢。因為固態(tài)存儲吞吐量提升,存儲軟件需要花費更多的CPU資源;因為固態(tài)存儲延遲性能的大幅提升,存儲軟件的處理延遲則開始凸顯??偨Y(jié)來說,隨著存儲介質(zhì)性能的進(jìn)一步提升,存儲軟件棧的性能和效率越來越成為存儲系統(tǒng)的瓶頸。 如圖7,SPDK(Storage Performance Development Kit,存儲性能開發(fā)套件)利用了很多DPDK的組件,在DPDK的基礎(chǔ)上,加入了存儲的相關(guān)組件。SPDK的核心技術(shù)依然是用戶態(tài)的PMD。SPDK已經(jīng)證明,使用一些處理器內(nèi)核和一些NVMe驅(qū)動器進(jìn)行存儲,而無需額外的卸載硬件,可以輕松實現(xiàn)每秒數(shù)百萬個IO。
圖7 SPDK基于DPDK和一些新的組件 SPDK由許多組件組成,這些組件相互連接并共享用戶態(tài)和輪詢模式操作的通用功能。每個組件都是為了克服特定場景的性能瓶頸而開發(fā)的,并且,每個組件也可以集成到非SPDK架構(gòu)中,從而使客戶可以利用SPDK的技術(shù)來加速自己的軟件應(yīng)用。從底層到上層,SPDK的組件包括:
用戶態(tài)PMD驅(qū)動:基于PCIe的NVMe驅(qū)動、NVMeoF驅(qū)動,以及英特爾QuickData驅(qū)動(QuickData為Intel志強處理器平臺的IO加速引擎)。
后端塊設(shè)備:Ceph RADOS塊設(shè)備(Ceph為開源的分布式存儲系統(tǒng),RADOS為Ceph的分布式集群封裝),Blobstore塊設(shè)備(VM或數(shù)據(jù)庫交互的虛擬設(shè)備),Linux AIO(異步IO)。
存儲服務(wù):塊設(shè)備抽象層(bdev),Blobstore。
存儲協(xié)議:iSCSI Target端,NVMeoF Target端,vhost-scsi Target端,vhost-blk Target端。
編輯:黃飛
評論