0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

現(xiàn)代異步存儲(chǔ)訪問(wèn)API探索:libaio、io_uring和SPDK

SSDFans ? 來(lái)源:SSDFans ? 2023-06-27 10:54 ? 次閱讀

【摘要】

最近的高性能存儲(chǔ)設(shè)備暴露了現(xiàn)有軟件棧的低效,因而催生了對(duì)I/O棧的改進(jìn)。Linux內(nèi)核的最新API是io_uring。作者提供了第一個(gè)針對(duì)io_uring的深度研究,并且和libaio、SPDK比較,探討它的下性能和優(yōu)缺點(diǎn)。根據(jù)作者的發(fā)現(xiàn),(1)輪詢能極大影響性能(2)只要CPU核足夠多,io_uring可以提供和SPKD接近的性能(3)在多核CPU和多設(shè)備場(chǎng)景下擴(kuò)展需要仔細(xì)的考慮并且需要一個(gè)混合方案。最后,作者為存儲(chǔ)密集的應(yīng)用開發(fā)者提供了設(shè)計(jì)指導(dǎo)。

【三種API簡(jiǎn)介】

1、libaio

傳統(tǒng)的同步I/O接口包括read()、write()、pread()、pwrite()等,線程開始I/O操作后立刻進(jìn)入阻塞狀態(tài),直到I/O請(qǐng)求完成。而使用異步I/O接口,如aio,線程把I/O請(qǐng)求發(fā)送給內(nèi)核后可以繼續(xù)做其他工作,直到內(nèi)核把I/O請(qǐng)求完成的信號(hào)發(fā)送給線程。通常,異步I/O接口效率更高,其中的核心系統(tǒng)調(diào)用是io_submit(用于提交I/O請(qǐng)求)和io_getevents(用于獲得完成的I/O請(qǐng)求)。然而,在每個(gè)I/O操作中,libaio要依賴兩個(gè)系統(tǒng)調(diào)用,而且使用中斷的方式通知I/O請(qǐng)求的完成,這導(dǎo)致libaio的單個(gè)I/O性能并不好,如下圖。

wKgaomSaT36ATXX5AAC5EkLbN84947.png

2、SPDK

SPDK是Linux的高性能API。它在用戶空間映射了PCIe寄存器以配置CQ和SQ,用戶通過(guò)輪詢CQ來(lái)捕獲I/O請(qǐng)求的完成,而不需要中斷和系統(tǒng)調(diào)用。SPDK的缺點(diǎn)是它很復(fù)雜,而且相對(duì)于libaio適用范圍很窄。SPDK不支持文件系統(tǒng),也無(wú)法利用內(nèi)核存儲(chǔ)服務(wù),如訪問(wèn)控制、調(diào)度、QoS和配額管理。

3、io_uring

io_uring中和了上述兩類API的優(yōu)缺點(diǎn)。它在用戶空間實(shí)現(xiàn)了兩個(gè)環(huán)形數(shù)據(jù)結(jié)構(gòu),同時(shí)內(nèi)核可以訪問(wèn)它們,類似于NVMe的CQ和SQ,submission ring存儲(chǔ)了用戶提交的I/O請(qǐng)求,completion存儲(chǔ)了I/O請(qǐng)求的完成結(jié)果。用戶可以不通過(guò)系統(tǒng)調(diào)用插入和檢索兩個(gè)環(huán)。

io_uring提供的I/O機(jī)制有三種,如下圖:

wKgaomSaT36ARLTYAAGU84P2HQw751.png

默認(rèn)模式下,用戶可以通過(guò)io_uring_enter系統(tǒng)調(diào)用通知內(nèi)核新請(qǐng)求已經(jīng)提交到SQ中。用戶使用同一個(gè)io_uring_enter系統(tǒng)調(diào)用等待I/O請(qǐng)求完成。io_uring_enter支持中斷模式(a)和輪詢模式(b)。當(dāng)然,因?yàn)橛脩粢部梢栽L問(wèn)CQ,所以用戶可以自己輪詢CQ等待I/O請(qǐng)求完成,而不使用任何系統(tǒng)調(diào)用。并且,io_uring也可以使用一個(gè)內(nèi)核線程輪詢SQ,這樣在整個(gè)I/O操作中不會(huì)使用任何系統(tǒng)調(diào)用(c)。

【性能測(cè)試分析】

實(shí)驗(yàn)使用fio生成4KB隨機(jī)讀負(fù)載,不使用page cache。純讀負(fù)載能達(dá)到更高的IOPS,而高IOPS有助于分析不同API的可擴(kuò)展性趨勢(shì)和每個(gè)I/O操作的開銷。除了io_uring外,其他API均使用默認(rèn)配置。io_uring的配置如下:

(1)iou:上圖(a)的配置(默認(rèn)的fio參數(shù)

(2)iou+p:上圖(b)的配置(fio參數(shù)是hipri)

(3)iou+k:不使用系統(tǒng)調(diào)用,即使用內(nèi)核線程輪詢I/O的提交,同時(shí)應(yīng)用輪詢I/O的完成(fio的參數(shù)是sqthread_poll)

環(huán)境配置如下表:

wKgaomSaT36AUWTVAAEuj6neJqo304.png

P.S. 雖然io_uring里提供了io_uring_enter作為提交I/O請(qǐng)求和捕獲完成的I/O請(qǐng)求的統(tǒng)一接口,但FIO里面還是分開使用了(即調(diào)用了兩次io_uring_enter)。

1、理解輪詢

作者使用單個(gè)fio job、單個(gè)NVMe驅(qū)動(dòng)和單個(gè)CPU,在不同隊(duì)列深度下,測(cè)試三種API(libaio、io_uring和SPDK)的KIOPS,如下圖:

wKgZomSaT36AVsZIAAEg4GiFIj0004.png

每個(gè)IOPS下對(duì)應(yīng)的延遲中位數(shù)如下圖:

wKgaomSaT36ATWp8AACuiL31JJU496.png

平均每個(gè)I/O操作進(jìn)行的系統(tǒng)調(diào)用個(gè)數(shù)如下圖:

wKgZomSaT36AWkQnAADl4E4JssY659.png

① 可知,iou+k的KIOPS僅僅13,比其他API少一個(gè)數(shù)量級(jí)。因?yàn)榇藭r(shí)fio線程和內(nèi)核輪詢線程共享一個(gè)CPU,減少了FIO每秒處理的I/O請(qǐng)求的數(shù)量。同時(shí),iou+k的延遲是8ms,比其他API慢1~2個(gè)數(shù)量級(jí)。iou+k的延遲不隨KIOPS的變化而變化,因?yàn)榇藭r(shí)的延遲取決于CPU資源的競(jìng)爭(zhēng),而非排隊(duì)等待。

當(dāng)CPU數(shù)量增加到2時(shí),iou+k的性能完全恢復(fù)了,如下圖:

wKgaomSaT36ACZuPAAEcwpp-Xoo274.png

每個(gè)KIOPS對(duì)應(yīng)的延遲中位數(shù)為:

wKgZomSaT36AbFSpAACWfuqQZ0o750.png

此時(shí),iou+k的性能僅次于SPDK:最大帶寬比SPDK小18%,延遲和SPDK相當(dāng)。

②SPDK在所有場(chǎng)景下性能最好,也是唯一達(dá)到驅(qū)動(dòng)帶寬上限的API。SPDK和iou+k的區(qū)別在于,iou+k使用兩個(gè)線程訪問(wèn)同一個(gè)變量,會(huì)產(chǎn)生原子訪問(wèn)和緩存失效的開銷,而SPDK使用一個(gè)線程,能更加充分的利用資源。

③ 當(dāng)IOPS較小時(shí),iou+p的性能和SPDK接近,因?yàn)殛?duì)列深度較小時(shí),系統(tǒng)調(diào)用的開銷還不足以成為性能瓶頸,此時(shí)系統(tǒng)態(tài)輪詢和用戶態(tài)輪詢的性能接近。類似的還有iou和libaio,當(dāng)隊(duì)列深度小于16時(shí),二者KIOPS和延遲都很接近,當(dāng)隊(duì)列深度大于16后,iou的KIOPS和延遲比libaio要好——因?yàn)閕ou使用的系統(tǒng)調(diào)用比libaio少,所以可以更加充分的利用CPU資源。

當(dāng)隊(duì)列深度小于16時(shí),iou的系統(tǒng)調(diào)用比iou+p少,但延遲比iou+p高。原因是,隊(duì)列較淺時(shí),fio的隊(duì)列很快會(huì)被填滿,而當(dāng)隊(duì)列滿時(shí),fio會(huì)等待至少一個(gè)請(qǐng)求完成再進(jìn)行下一步動(dòng)作。此時(shí),雖然中斷比較慢,但iou可能會(huì)一次處理較多完成的請(qǐng)求,而輪詢則是檢測(cè)到一個(gè)請(qǐng)求完成就退出,從而錯(cuò)失了批量處理多個(gè)完成的請(qǐng)求的機(jī)會(huì)。當(dāng)隊(duì)列深度增加時(shí),兩個(gè)API最后都趨向于每個(gè)I/O請(qǐng)求只使用1個(gè)系統(tǒng)調(diào)用。

iou和libaio的最大區(qū)別是,iou多了一個(gè)提交隊(duì)列(SQ),這就是它具有批處理能力的原因。

2、不同的CPU-設(shè)備比

作者進(jìn)一步分析了對(duì)于iou+k,每個(gè)驅(qū)動(dòng)需要多少個(gè)CPU以獲得最佳性能。此時(shí),作者使用了J=5個(gè)FIO job測(cè)試,每個(gè)job運(yùn)行在不同的驅(qū)動(dòng)上,隊(duì)列深度為128,C代表CPU的數(shù)目,本次實(shí)驗(yàn)中,分別測(cè)試了C=J,C=J+1,C=J+2和C=J*2的情況。

注意,在iou+k中,內(nèi)核會(huì)為每個(gè)job產(chǎn)生一個(gè)內(nèi)核線程以輪詢SQ獲得提交的請(qǐng)求。

實(shí)驗(yàn)結(jié)果如下圖:

wKgZomSaT36ARjbcAAFlUh5iE9c475.png

可見,除了iou+k,其他API的帶寬表現(xiàn)和CPU-設(shè)備比無(wú)關(guān)。而iou+k需要兩倍于驅(qū)動(dòng)數(shù)的CPU才能達(dá)到最好的性能——即每個(gè)線程需要一個(gè)單獨(dú)的CPU來(lái)輪詢。糟糕的是,當(dāng)CPU數(shù)不是最佳時(shí),iou+k的KIOPS是最低的。這一實(shí)驗(yàn)結(jié)果揭示了iou+k要實(shí)現(xiàn)高性能的隱藏開銷,而其他測(cè)試忽略了這一點(diǎn)。

3、可擴(kuò)展性

作者控制job從1到20,以測(cè)試不同API的可擴(kuò)展性。每個(gè)job訪問(wèn)不同的驅(qū)動(dòng),設(shè)置CPU數(shù)C=2*J(由于硬件限制,C最大可以取到20),隊(duì)列深度為128。下圖是測(cè)試結(jié)果:

wKgZomSaT36AMWjrAAHrO1xNNIA251.png

SPDK的性能總是最好的,而性能第二好的API取決于job的數(shù)量和CPU核的數(shù)量。當(dāng)J不大于10時(shí),iou+k可以給每個(gè)內(nèi)核線程分配一個(gè)CPU,性能最好。此后隨著J的增大,內(nèi)核線程和應(yīng)用線程開始搶奪CPU資源,KIOPS開始下滑。在J=12時(shí),iou+k和iou、iou+p的KIOPS交匯,在J=14時(shí),iou+k成為性能最差的API。其他的API隨著job的增長(zhǎng),KIOPS也基本上穩(wěn)定增長(zhǎng)。

iou和iou+p的性能很接近,libaio的帶寬也僅僅比iou、iou+p少10%。

【總結(jié)與討論】

1、不同的輪詢方式各有特點(diǎn)

lSPDK的優(yōu)勢(shì)不僅僅體現(xiàn)在用戶態(tài)輪詢、無(wú)系統(tǒng)調(diào)用開銷,還體現(xiàn)在使用單個(gè)線程進(jìn)行輪詢。

liou+k的優(yōu)勢(shì)在CPU不夠時(shí)不明顯。

liou+p使用系統(tǒng)級(jí)輪詢,在隊(duì)列深度較小時(shí)可以和SPDK相當(dāng)。

2、io_uring在特定配置下的性能接近SPDK

3、性能的可擴(kuò)展性需要仔細(xì)考慮

雖然SPDK的性能最好,但需要放棄Linux文件的支持。如果需要使用文件系統(tǒng),且CPU足夠多,iou+k是不錯(cuò)的選擇(可以達(dá)到90% SPDK的性能),而若CPU資源不足,可以使用iou+p,當(dāng)隊(duì)列深度不深時(shí)和SPDK的性能接近。

未來(lái)可以在更在實(shí)際的I/O密集型應(yīng)用上測(cè)試,如數(shù)據(jù)庫(kù)。它們都需要文件系統(tǒng)的支持,可能會(huì)帶來(lái)額外的同步開銷,可能會(huì)覆蓋I/O路徑上的bottleneck。此外還可以研究更高效的iou+k設(shè)計(jì),如不同的應(yīng)用線程共享一個(gè)內(nèi)核輪詢線程,或者二者更好的使用CPU資源等。最后,io_uring支持socket I/O,所以它的性能也可以測(cè)試以評(píng)估網(wǎng)絡(luò)應(yīng)用的表現(xiàn)。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    10782

    瀏覽量

    210542
  • 接口
    +關(guān)注

    關(guān)注

    33

    文章

    8381

    瀏覽量

    150583
  • 存儲(chǔ)
    +關(guān)注

    關(guān)注

    13

    文章

    4180

    瀏覽量

    85504
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1469

    瀏覽量

    61701
  • 線程
    +關(guān)注

    關(guān)注

    0

    文章

    502

    瀏覽量

    19620

原文標(biāo)題:現(xiàn)代異步存儲(chǔ)訪問(wèn)API探索:libaio、io_uring和SPDK

文章出處:【微信號(hào):SSDFans,微信公眾號(hào):SSDFans】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux驅(qū)動(dòng)學(xué)習(xí)筆記:異步IO

    前幾篇介紹了幾種IO模型,今天介紹另一種IO模型——異步IO。
    發(fā)表于 06-12 16:24 ?642次閱讀

    請(qǐng)教關(guān)于c6747的EMIFA訪問(wèn)外部16位異步存儲(chǔ)設(shè)備的地址總線問(wèn)題

    大家好,我要使用C6747的EMIFA訪問(wèn)外部16位異步存儲(chǔ)設(shè)備,現(xiàn)在要讓片選cs4有效,EMA_A12位為1,根據(jù)手冊(cè)上的圖16位模式下,EMA_A12位對(duì)應(yīng)的是外部設(shè)備地址的A13位,片選cs4
    發(fā)表于 07-25 07:16

    異步IO是什么

    python 異步ioAsync IO is a concurrent programming design that has received dedicated support
    發(fā)表于 09-06 07:26

    《Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解》第9章、Linux設(shè)備驅(qū)動(dòng)中的異步通知與異步IO

    《Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解》第9章、Linux設(shè)備驅(qū)動(dòng)中的異步通知與異步IO
    發(fā)表于 10-27 11:33 ?0次下載
    《Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解》第9章、Linux設(shè)備驅(qū)動(dòng)中的<b class='flag-5'>異步</b>通知與<b class='flag-5'>異步</b><b class='flag-5'>IO</b>

    超全的SPDK性能評(píng)估指南

    SPDK采用異步I/O(Asynchronous I/O)加輪詢(Polling)的工作模式,通常與Kernel的異步I/O作為對(duì)比。在此,主要介紹通過(guò)使用fio評(píng)估Kernel異步I
    的頭像 發(fā)表于 11-26 09:58 ?8887次閱讀

    不同應(yīng)用程序的存儲(chǔ)IO類型解析

    的數(shù)據(jù)訪問(wèn)類型有所不同。 本文描述典型的不同應(yīng)用程序的存儲(chǔ)IO類型。幫助讀者了解不同應(yīng)用程序存儲(chǔ)IO類型的同時(shí),提供的數(shù)據(jù)也可以為
    的頭像 發(fā)表于 11-30 15:21 ?2196次閱讀
    不同應(yīng)用程序的<b class='flag-5'>存儲(chǔ)</b><b class='flag-5'>IO</b>類型解析

    io_uring 優(yōu)化 nginx,基于通用應(yīng)用 nginx 的實(shí)戰(zhàn)

    了網(wǎng)絡(luò)編程相關(guān)的API,對(duì)用戶提供sendmsg、recvmsg、accept、connect等接口的異步支持,將io_uring的生態(tài)范圍擴(kuò)大到了網(wǎng)絡(luò)領(lǐng)域。 另外從Linux v5.7開始
    的頭像 發(fā)表于 10-10 16:19 ?3020次閱讀
    <b class='flag-5'>io_uring</b> 優(yōu)化 nginx,基于通用應(yīng)用 nginx 的實(shí)戰(zhàn)

    SPDK Thread模型設(shè)計(jì)與實(shí)現(xiàn) NVMe-oF的使用案例

    SPDK Thread 模型是SPDK誕生以來(lái)十分重要的模塊,它的設(shè)計(jì)確保了spdk應(yīng)用的無(wú)鎖化編程模型,本文基于spdk最新的release 19.07版本介紹了整體thread模型
    的頭像 發(fā)表于 07-03 16:20 ?2322次閱讀

    使用Ecobee API訪問(wèn)您的Ecobee恒溫器

    電子發(fā)燒友網(wǎng)站提供《使用Ecobee API訪問(wèn)您的Ecobee恒溫器.zip》資料免費(fèi)下載
    發(fā)表于 12-06 15:23 ?0次下載
    使用Ecobee <b class='flag-5'>API</b><b class='flag-5'>訪問(wèn)</b>您的Ecobee恒溫器

    Linux 6.0生命周期結(jié)束介紹

    在去年 10 月初,Linux 6.0 正式發(fā)布,當(dāng)時(shí)新版本帶來(lái)了非常多的新特性 / 功能,如 F2FS 低內(nèi)存模式、在使用 XFS 和 io_uring 時(shí)的異步緩沖寫入、對(duì) RISC-V 和 AArch64(ARM64)硬件架構(gòu)的改進(jìn),以及 Btrfs 和 Overl
    的頭像 發(fā)表于 01-16 11:43 ?761次閱讀

    信號(hào)驅(qū)動(dòng)IO異步IO的區(qū)別

    一. 談信號(hào)驅(qū)動(dòng)IO (對(duì)比異步IO來(lái)看) 信號(hào)驅(qū)動(dòng)IO 對(duì)比 異步 IO進(jìn)行理解 信號(hào)驅(qū)動(dòng)
    的頭像 發(fā)表于 11-08 15:32 ?926次閱讀
    信號(hào)驅(qū)動(dòng)<b class='flag-5'>IO</b>與<b class='flag-5'>異步</b><b class='flag-5'>IO</b>的區(qū)別

    linux異步io框架iouring應(yīng)用

    Linux內(nèi)核5.1支持了新的異步IO框架iouring,由Block IO大神也即Fio作者Jens Axboe開發(fā),意在提供一套公用的網(wǎng)絡(luò)和磁盤異步
    的頭像 發(fā)表于 11-08 15:39 ?587次閱讀
    linux<b class='flag-5'>異步</b><b class='flag-5'>io</b>框架iouring應(yīng)用

    異步IO框架iouring介紹

    前言 Linux內(nèi)核5.1支持了新的異步IO框架iouring,由Block IO大神也即Fio作者Jens Axboe開發(fā),意在提供一套公用的網(wǎng)絡(luò)和磁盤異步
    的頭像 發(fā)表于 11-09 09:30 ?1995次閱讀
    <b class='flag-5'>異步</b><b class='flag-5'>IO</b>框架iouring介紹

    SPDK在虛擬化場(chǎng)景下的使用方法

    一.概述 隨著越來(lái)越多公有云服務(wù)提供商采用SPDK技術(shù)作為其高性能云存儲(chǔ)的核心技術(shù)之一,intel推出的SPDK技術(shù)備受業(yè)界關(guān)注。本篇博文就和大家一起探索
    的頭像 發(fā)表于 11-10 10:12 ?1283次閱讀
    <b class='flag-5'>SPDK</b>在虛擬化場(chǎng)景下的使用方法

    io_uring內(nèi)核各個(gè)組件的性能

    先看看性能 io_uring 需要內(nèi)核版本在5.1 及以上才支持,liburing的編譯安裝 很簡(jiǎn)單,直接clone 官方的代碼,sudo make sudo make install 就好了,本文
    的頭像 發(fā)表于 11-10 11:46 ?1305次閱讀
    <b class='flag-5'>io_uring</b>內(nèi)核各個(gè)組件的性能