一、總體介紹
1.1 背景介紹
近年來(lái),隨著存儲(chǔ)硬件的革新與網(wǎng)絡(luò)技術(shù)的突飛猛進(jìn),如NVMe SSD和超高速網(wǎng)絡(luò)接口的普及應(yīng)用,I/O性能瓶頸已得到顯著改善。然而,在2020年及以后的技術(shù)背景下,盡管SSD速度通過(guò)NVMe接口得到了大幅提升,并且網(wǎng)絡(luò)傳輸速率也進(jìn)入了新的高度,但CPU主頻發(fā)展并未保持同等步調(diào),3GHz左右的核心頻率已成為常態(tài)。
在當(dāng)前背景下Apache Spark等大數(shù)據(jù)處理工具中,盡管存儲(chǔ)和網(wǎng)絡(luò)性能的提升極大地減少了數(shù)據(jù)讀取和傳輸?shù)臅r(shí)間消耗,但Apache Spark框架基于類(lèi)火山模型的行式處理,在執(zhí)行復(fù)雜查詢(xún)、迭代計(jì)算時(shí)對(duì)現(xiàn)代CPU并行計(jì)算特性和向量化計(jì)算優(yōu)勢(shì)的利用率仍然有待提高。同時(shí),傳統(tǒng)TCP/IP網(wǎng)絡(luò)通信模式下,CPU承擔(dān)了大量的協(xié)議解析、包構(gòu)建和錯(cuò)誤處理任務(wù),進(jìn)一步降低了整體數(shù)據(jù)處理效率,這導(dǎo)致Apache Spark 在實(shí)際運(yùn)行中并沒(méi)有達(dá)到網(wǎng)絡(luò)、磁盤(pán)、CPU的IO瓶頸。
1.2 挑戰(zhàn)和困難
在Apache Spark的數(shù)據(jù)處理流程中,如上圖所示,整個(gè)過(guò)程從數(shù)據(jù)源開(kāi)始,首先經(jīng)歷數(shù)據(jù)加載階段。Spark作業(yè)啟動(dòng)時(shí),任務(wù)被分配到各個(gè)運(yùn)算節(jié)點(diǎn)(executor),它們從諸如HDFS、S3(Amazon Simple Storage Service)或其他支持的存儲(chǔ)系統(tǒng)中高效地獲取數(shù)據(jù)。
一旦數(shù)據(jù)成功加載至內(nèi)存或磁盤(pán)上,運(yùn)算節(jié)點(diǎn)首先開(kāi)始數(shù)據(jù)的解壓縮工作,然后執(zhí)行相應(yīng)的計(jì)算操作,例如map、filter、reduceByKey等轉(zhuǎn)換操作。
接下來(lái),在執(zhí)行涉及不同分區(qū)間數(shù)據(jù)交換的操作(如join、groupByKey)時(shí),Spark會(huì)觸發(fā)Shuffle階段。在這個(gè)階段,各個(gè)executor將計(jì)算后的中間結(jié)果按照特定鍵值進(jìn)行排序,并通過(guò)網(wǎng)絡(luò)傳輸至其他executor,以便進(jìn)行進(jìn)一步的合并和聚集操作。
完成Shuffle后,數(shù)據(jù)再次經(jīng)過(guò)一輪或多輪計(jì)算處理,以產(chǎn)出最終結(jié)果。當(dāng)所有任務(wù)完成后,結(jié)果數(shù)據(jù)會(huì)被壓縮后寫(xiě)回目標(biāo)存儲(chǔ)系統(tǒng),如HDFS、數(shù)據(jù)庫(kù)或其他外部服務(wù),從而完成整個(gè)數(shù)據(jù)處理生命周期。
綜上所述,在Apache Spark的數(shù)據(jù)處理過(guò)程中,盡管其設(shè)計(jì)高度優(yōu)化,但仍面臨多個(gè)技術(shù)挑戰(zhàn):
首先,傳統(tǒng)硬件中,數(shù)據(jù)傳輸需要CPU解碼并通過(guò)PCIe總線(xiàn)多次搬運(yùn)至內(nèi)存和硬件,使用反彈緩沖區(qū),雖然是臨時(shí)存儲(chǔ)但也增加復(fù)雜度與延遲;列式存儲(chǔ)(Parquet、ORC)高效壓縮同類(lèi)數(shù)據(jù)減少I(mǎi)/O,但讀取時(shí)的解壓和編解碼操作加重了CPU負(fù)擔(dān),尤其在僅需處理部分列時(shí)效率下降;Apache Spark采用行式處理,如DataSourceScanExec按行掃描可能導(dǎo)致冗余加載,并因頻繁調(diào)用“next”及虛函數(shù)引發(fā)CPU中斷,全行掃描對(duì)部分列查詢(xún)性能損耗顯著。
其次,隨著數(shù)據(jù)量不斷激增以及IO技術(shù)的提升,基于CPU的優(yōu)化帶來(lái)的收益越來(lái)越不明顯,傳統(tǒng)的CPU算力逐漸成為計(jì)算瓶頸。在涉及特定算子操作時(shí),性能問(wèn)題尤為突出。例如,高散列度數(shù)據(jù)的 join,高散列度數(shù)據(jù)的 aggregate。在執(zhí)行join操作時(shí),尤其當(dāng)采用基于哈希的join策略時(shí),因?yàn)閿?shù)據(jù)散列程度越高,哈希計(jì)算的負(fù)載就越大,對(duì)CPU和內(nèi)存的計(jì)算能力要求也就越高。哈希計(jì)算是一個(gè)計(jì)算密集型任務(wù),需要CPU執(zhí)行大量的計(jì)算操作,并且可能涉及到內(nèi)存的讀取和寫(xiě)入。當(dāng)數(shù)據(jù)散列程度較高時(shí),哈希計(jì)算的復(fù)雜度增加,可能導(dǎo)致CPU和內(nèi)存的使用率增加,從而影響系統(tǒng)的整體性能。其次,數(shù)據(jù)散列程度較高可能會(huì)增加哈希沖突的概率,進(jìn)而影響內(nèi)存的使用效率。當(dāng)哈希沖突較多時(shí),可能需要額外的操作來(lái)解決沖突,例如使用鏈表或者開(kāi)放地址法來(lái)處理沖突。這些額外的操作可能會(huì)占用額外的內(nèi)存空間,并且增加內(nèi)存的讀寫(xiě)次數(shù),從而降低內(nèi)存的使用效率。
此外,Shuffle作為Spark計(jì)算框架中決定整體性能的關(guān)鍵環(huán)節(jié)之一,其內(nèi)部包含了多次序列化與反序列化過(guò)程、跨節(jié)點(diǎn)網(wǎng)絡(luò)傳輸以及磁盤(pán)IO操作等復(fù)雜行為。這些操作不僅增加了系統(tǒng)開(kāi)銷(xiāo),而且可能導(dǎo)致數(shù)據(jù)局部性的喪失,進(jìn)一步拖慢整個(gè)任務(wù)的執(zhí)行速度。因此,如何優(yōu)化Shuffle過(guò)程,減小其對(duì)系統(tǒng)資源的影響,是Spark性能調(diào)優(yōu)的重要方向。
因此,面對(duì)硬件條件的新格局,開(kāi)發(fā)者不僅需要深入研究如何優(yōu)化Apache Spark內(nèi)部機(jī)制以適應(yīng)大規(guī)模并行計(jì)算需求,還應(yīng)探索將特定類(lèi)型的數(shù)據(jù)運(yùn)算任務(wù)轉(zhuǎn)移到諸如GPU、FPGA或其他專(zhuān)用加速器等更高效能的硬件上,從而在CPU資源有限的情況下,實(shí)現(xiàn)更高層次的大數(shù)據(jù)處理性能提升。
二、整體方案
我們采用軟硬件結(jié)合方式,無(wú)侵入式的集成Apache Spark,并在Spark數(shù)據(jù)計(jì)算全鏈路的3大方面都進(jìn)行了全面提升和加速。
在「數(shù)據(jù)加載」方面,自研的DPU數(shù)據(jù)加載引擎直讀硬件存儲(chǔ)的數(shù)據(jù)到計(jì)算卡中,優(yōu)化掉大量的內(nèi)存與加速卡的PCIe數(shù)據(jù)傳輸性能損耗,同時(shí)在計(jì)算卡中進(jìn)行數(shù)據(jù)的解壓縮計(jì)算。同理在最后的結(jié)果輸出階段,也在計(jì)算卡中進(jìn)行數(shù)據(jù)壓縮。
在「離線(xiàn)計(jì)算」方面,自研的DPU計(jì)算引擎擁有強(qiáng)大的計(jì)算能力、容錯(cuò)能力、并滿(mǎn)足 Spark 引擎日益復(fù)雜的離線(xiàn)處理場(chǎng)景和機(jī)器學(xué)習(xí)場(chǎng)景。
在「數(shù)據(jù)傳輸」方面,采用基于遠(yuǎn)程直接內(nèi)存訪(fǎng)問(wèn)(RDMA)技術(shù),以提高集群間的數(shù)據(jù)傳輸效率。
三、核心加速階段
加速階段如下圖所示,核心數(shù)據(jù)加速分為四個(gè)部分,分別為 1.數(shù)據(jù)讀取階段;2.任務(wù)處理階段;3.Shuffle數(shù)據(jù)傳輸階段;4.數(shù)據(jù)輸出階段。
3.1數(shù)據(jù)加載階段
3.1.1 面臨挑戰(zhàn)
在Apache Spark的數(shù)據(jù)處理流程中,數(shù)據(jù)加載階段是整個(gè)ELT(Extract, Load, Transform)作業(yè)的關(guān)鍵起始步驟。首先,當(dāng)從傳統(tǒng)硬件架構(gòu)的數(shù)據(jù)源加載本地?cái)?shù)據(jù)時(shí),面臨如下挑戰(zhàn):
數(shù)據(jù)傳輸瓶頸:在傳統(tǒng)的硬件體系結(jié)構(gòu)中,數(shù)據(jù)加載過(guò)程涉及到多次通過(guò)CPU和PCIe總線(xiàn)的搬運(yùn)操作。具體而言,每一份數(shù)據(jù)需要先從數(shù)據(jù)源經(jīng)過(guò)CPU解碼并通過(guò)PCIe通道傳輸至系統(tǒng)內(nèi)存,然后再次經(jīng)由CPU控制并經(jīng)過(guò)PCIe接口發(fā)送到特定硬件如GPU進(jìn)行進(jìn)一步處理。在此過(guò)程中,“反彈緩沖區(qū)”作為臨時(shí)存儲(chǔ)區(qū)域,在系統(tǒng)內(nèi)存中起到了橋接不同設(shè)備間數(shù)據(jù)傳輸?shù)淖饔?,但這也會(huì)增加數(shù)據(jù)搬移的復(fù)雜性和潛在延遲。
列式存儲(chǔ)的優(yōu)勢(shì)與挑戰(zhàn):在大數(shù)據(jù)環(huán)境中,列式存儲(chǔ)格式如Parquet和ORC等被廣泛采用,因其高效性而備受青睞。由于同一列中的數(shù)據(jù)類(lèi)型相同,可以實(shí)現(xiàn)高效的壓縮率,并且內(nèi)存訪(fǎng)問(wèn)模式相對(duì)線(xiàn)性,從而減少I(mǎi)/O開(kāi)銷(xiāo)。然而,這也帶來(lái)了問(wèn)題,即在讀取數(shù)據(jù)前必須進(jìn)行解壓縮處理,這無(wú)疑增加了CPU額外的計(jì)算負(fù)擔(dān),尤其是在需要對(duì)部分列進(jìn)行運(yùn)算的情況下。
行式處理效率考量:在早期版本或某些特定場(chǎng)景下,Apache Spark在執(zhí)行物理計(jì)劃時(shí)傾向于行式處理數(shù)據(jù)。例如DataSourceScanExec算子負(fù)責(zé)底層數(shù)據(jù)源掃描,其默認(rèn)按行讀取數(shù)據(jù),這種策略可能導(dǎo)致不必要的列數(shù)據(jù)冗余加載及頻繁調(diào)用“next”方法獲取下一行記錄。這一過(guò)程中,大量的虛函數(shù)調(diào)用可能引發(fā)CPU中斷,降低了處理效率,特別是在僅關(guān)注部分列時(shí),會(huì)因?yàn)槿袙呙瓒腩~外的性能損失。
在數(shù)據(jù)壓縮解壓縮過(guò)程中,壓縮解壓縮策略選擇階段是整個(gè)過(guò)程的開(kāi)始。傳統(tǒng)的硬件體系結(jié)構(gòu)中,數(shù)據(jù)的壓縮和解壓縮過(guò)程通常只能依賴(lài)CPU完成,沒(méi)有其他策略可以選擇,從而無(wú)法利用GPU、DPU等其他處理器資源。這種局限性導(dǎo)致數(shù)據(jù)壓縮解壓縮過(guò)程會(huì)大量占用CPU資源,同時(shí),與DPU相比,CPU的并行處理能力相對(duì)較弱,無(wú)法充分發(fā)揮硬件資源的潛力。在大規(guī)模數(shù)據(jù)處理的場(chǎng)景下,數(shù)據(jù)壓縮解壓縮過(guò)程可能成為CPU的瓶頸,導(dǎo)致系統(tǒng)性能下降。此外,由于數(shù)據(jù)壓縮解壓縮是一個(gè)計(jì)算密集型任務(wù),當(dāng)系統(tǒng)中同時(shí)存在其他需要CPU資源的任務(wù)時(shí),壓縮解壓縮過(guò)程可能會(huì)與其他任務(wù)產(chǎn)生競(jìng)爭(zhēng),進(jìn)一步加劇了CPU資源的緊張程度,導(dǎo)致系統(tǒng)整體的響應(yīng)速度變慢。
3.1.2 解決方案與原理
在DPU(Data Processing Unit)架構(gòu)設(shè)計(jì)中,采用了一種直接內(nèi)存訪(fǎng)問(wèn)(DMA)技術(shù),該技術(shù)構(gòu)建了從DPU內(nèi)存到存儲(chǔ)設(shè)備之間直接的數(shù)據(jù)傳輸路徑。相較于傳統(tǒng)的數(shù)據(jù)讀取方式,DMA機(jī)制有效地消除了CPU及其回彈緩沖區(qū)作為中間環(huán)節(jié)的必要性,從而顯著提升了系統(tǒng)的數(shù)據(jù)傳輸帶寬,并減少了由數(shù)據(jù)中轉(zhuǎn)造成的CPU延遲以及利用率壓力。
具體而言,在DPU系統(tǒng)內(nèi)部或與之緊密集成的存儲(chǔ)設(shè)備(例如NVMe SSD)上,內(nèi)置了支持DMA功能的引擎,允許數(shù)據(jù)塊以高效、直接的方式在存儲(chǔ)介質(zhì)與DPU內(nèi)存之間進(jìn)行雙向傳遞。為了確保這一過(guò)程的精確執(zhí)行,系統(tǒng)精心設(shè)計(jì)了針對(duì)DMA操作的專(zhuān)用機(jī)制和緩存管理策略,其中包含了由存儲(chǔ)驅(qū)動(dòng)程序發(fā)起的DMA回調(diào)函數(shù),用于驗(yàn)證并轉(zhuǎn)換DPU內(nèi)存中的虛擬地址至物理地址,進(jìn)而保證數(shù)據(jù)能夠準(zhǔn)確無(wú)誤地從NVMe設(shè)備復(fù)制到DPU指定的內(nèi)存區(qū)域。
當(dāng)應(yīng)用程序通過(guò)虛擬文件系統(tǒng)(VFS)向底層硬件提交DPU緩沖區(qū)地址作為DMA目標(biāo)位置時(shí),用戶(hù)空間庫(kù)將捕獲這些特定于DPU的緩沖區(qū)地址,并將其替換為原本提交給VFS的代理CPU緩沖區(qū)地址。在實(shí)際執(zhí)行DMA操作之前,運(yùn)行于DPU環(huán)境的軟件會(huì)在適當(dāng)?shù)臅r(shí)機(jī)調(diào)用相關(guān)接口,識(shí)別出原始的CPU緩沖區(qū)地址,并重新提供有效的DPU緩沖區(qū)地址,以便DMA操作能正確且高效地進(jìn)行。由此,在不增加CPU處理負(fù)擔(dān)的前提下,實(shí)現(xiàn)了NVMe設(shè)備與DPU內(nèi)存間數(shù)據(jù)塊遷移的高度優(yōu)化流程。
3.1.3 優(yōu)勢(shì)與效果
吞吐提升:CPU的PCIe吞吐可能低于DPU的吞吐能力。這種差異是由于基于服務(wù)器的PCIe拓?fù)涞紺PU的PCIe路徑較少。如圖所示DPU支持直接數(shù)據(jù)路徑(綠色),而非通過(guò)CPU中的反彈緩沖區(qū)間接讀取的路徑(紅色)。這可以提高帶寬、降低延遲并減少CPU和DPU吞吐量負(fù)載。
降低延遲:DPU直讀數(shù)據(jù)路徑只有一個(gè)副本,直接從源到目標(biāo)。如果CPU執(zhí)行數(shù)據(jù)移動(dòng),則延遲可能會(huì)受到CPU可用性沖突的影響,這可能會(huì)導(dǎo)致抖動(dòng)。DPU緩解了這些延遲問(wèn)題。
提升CPU利用率:如果使用CPU移動(dòng)數(shù)據(jù),則投入到數(shù)據(jù)搬運(yùn)的CPU利用率會(huì)增加,并干擾CPU上的其余工作。使用DPU可減少CPU在數(shù)據(jù)搬用的工作負(fù)載,使應(yīng)用程序代碼能夠在更短的時(shí)間內(nèi)運(yùn)行。
解壓縮:DPU讀取parquet文件的同時(shí)會(huì)將文件解壓,不用通過(guò)CPU進(jìn)行編譯碼與解壓計(jì)算,直接進(jìn)行謂詞下推減少讀取數(shù)據(jù)量從而提升數(shù)據(jù)讀取效率。
更適合列式處理數(shù)據(jù)結(jié)構(gòu):列式數(shù)據(jù)結(jié)構(gòu)在運(yùn)算中有更好的性能,有利于Spark的Catalyst優(yōu)化器做出更加智能的決策,如過(guò)濾條件下推、列剪枝等,減少了不必要的計(jì)算和數(shù)據(jù)移動(dòng)。在執(zhí)行階段會(huì)對(duì)列式數(shù)據(jù)進(jìn)行向量化操作,將多條記錄打包成一個(gè)批次進(jìn)行處理,提升運(yùn)算效率。
3.2離線(xiàn)計(jì)算階段
3.2.1 面臨挑戰(zhàn)
2015年基于Spark Summit調(diào)研顯示,2010年硬件的基本情況是存50+MB/s(HDD),網(wǎng)絡(luò)是1Gpbs,CPU是~3GHz;五年后,存儲(chǔ)和網(wǎng)絡(luò)都有了10倍以上的提升,但是CPU卻并沒(méi)有什么變化。
2020年,硬件的變化讓io性能有了進(jìn)一步提升。SSD有了NVMe接口,同時(shí)有了超高速網(wǎng)絡(luò),但CPU仍然是3赫茲。那么當(dāng)下我們的挑戰(zhàn)是在這樣的硬件條件下,如何最大化CPU性能,如何使用更高效的硬件替代CPU進(jìn)行專(zhuān)業(yè)數(shù)據(jù)運(yùn)算。
3.2.2 解決方案與原理
我們考慮如何將具有高性能計(jì)算能力的DPU用到 Spark 里來(lái),從而提升 Spark 的計(jì)算性能,突破 CPU 瓶頸。接下來(lái)將介紹DPU計(jì)算引擎:
上圖是DPU的整體設(shè)計(jì)。目前支持的算子覆蓋Spark生產(chǎn)環(huán)境常用算子,包括Scan、Filter、Project、Union、Hash Aggregation、Sort、Join、Exchange等。表達(dá)式方面,我們開(kāi)發(fā)了目前生產(chǎn)環(huán)境常用的布爾函數(shù)、Sum/Count/AVG/Max/Min等聚合函數(shù)。
在整個(gè)流轉(zhuǎn)過(guò)程中,RACE Plugin層起到承上啟下的關(guān)系:
1. 最核心的是Plan Conversion組件,在Spark優(yōu)化 Physical Plan時(shí),會(huì)應(yīng)用一批規(guī)則,Race通過(guò)插入的自定義規(guī)則可以攔截到優(yōu)化后的Physical Plan,如果發(fā)現(xiàn)當(dāng)前算子上的所有表達(dá)式可以下推給DPU,那么替換Spark原生算子為相應(yīng)的可以在DPU上執(zhí)行的自定義算子,由HADOS將其下推給DPU 來(lái)執(zhí)行并返回結(jié)果。
2. Fallback組件,Spark支持的Operator和Expression非常多,在Race研發(fā)初期,無(wú)法 100% 覆蓋 Spark 查詢(xún)執(zhí)行計(jì)劃中的算子和表達(dá)式,因此 Race必須有先前兼容回退執(zhí)行的能力。
3. Strategy組件, 因?yàn)閒allback 這個(gè) operator 前后插入行轉(zhuǎn)列、列轉(zhuǎn)行的算子。因?yàn)檫@兩次轉(zhuǎn)換對(duì)整個(gè)執(zhí)行的過(guò)程的性能損耗是很大的。針對(duì)這種情況,最穩(wěn)妥的方式就是整個(gè)子樹(shù)Query全部回退到CPU,而選擇哪些情況下執(zhí)行這個(gè)操作至關(guān)重要。
4. Metric組件,Race會(huì)收集DPU執(zhí)行過(guò)程中的指標(biāo)統(tǒng)計(jì),然后上報(bào)給Spark的Metrics System做展示、Debug、API調(diào)用。
3.2.3 優(yōu)勢(shì)與效果
通過(guò)Spark Plugin機(jī)制成功地將Spark計(jì)算任務(wù)卸載至DPU上執(zhí)行,充分利用了DPU強(qiáng)大的計(jì)算處理能力,有效解決了CPU在復(fù)雜數(shù)據(jù)處理中的性能瓶頸問(wèn)題。經(jīng)過(guò)一系列詳盡的測(cè)試與驗(yàn)證,在TPC-DS基準(zhǔn)測(cè)試中99條SQL語(yǔ)句的執(zhí)行表現(xiàn)顯著提升:
顯著提高查詢(xún)性能:本方案在相同硬件條件下,使得單個(gè)查詢(xún)的執(zhí)行時(shí)間最多可縮短到原來(lái)的四分之一左右,即最高性能提升達(dá)到4.48倍;而在表達(dá)式操作層面,性能優(yōu)化效果更為突出,某些情況下甚至能提升至原始速度的8.47倍。
算子級(jí)加速明顯:在對(duì)關(guān)鍵算子如Filter和哈希聚合操作進(jìn)行評(píng)估時(shí),相較于原生Spark解決方案,F(xiàn)ilter算子的執(zhí)行效率提升了高達(dá)43倍,而哈希聚合算子性能也提升了13倍。這得益于我們減少了列式數(shù)據(jù)轉(zhuǎn)換為行式數(shù)據(jù)的額外開(kāi)銷(xiāo),以及DPU硬件層面對(duì)運(yùn)算密集型任務(wù)的強(qiáng)大加速作用。
大幅度降低CPU資源占用:通過(guò)DPU加速卸載后,系統(tǒng)資源利用率得到顯著改善。在TPC-DS測(cè)試場(chǎng)景下,CPU平均使用率從60%大幅下降至5%,釋放出更多CPU資源用于其他業(yè)務(wù)邏輯處理,增強(qiáng)了系統(tǒng)的整體并發(fā)能力和響應(yīng)速度。
3.3數(shù)據(jù)傳輸階段
3.3.1 面臨挑戰(zhàn)
在Apache Spark的數(shù)據(jù)處理框架中,Shuffle階段扮演著至關(guān)重要的角色,然而,該過(guò)程因其涉及大規(guī)模數(shù)據(jù)在網(wǎng)絡(luò)中的傳輸而顯著增加了執(zhí)行時(shí)間,容易成為制約Spark作業(yè)性能的關(guān)鍵瓶頸環(huán)節(jié)。傳統(tǒng)的網(wǎng)絡(luò)通信機(jī)制在 Shuffle 過(guò)程中的表現(xiàn)不盡如人意。具體表現(xiàn)為:
· 數(shù)據(jù)的發(fā)送和接收過(guò)程中,操作系統(tǒng)內(nèi)核參與了必要的管理與調(diào)度工作,這一介入導(dǎo)致了額外的延遲開(kāi)銷(xiāo)。每個(gè)數(shù)據(jù)單元在經(jīng)過(guò)操作系統(tǒng)的網(wǎng)絡(luò)協(xié)議棧進(jìn)行傳遞時(shí),需歷經(jīng)多次上下文切換以及數(shù)據(jù)復(fù)制操作,這些都無(wú)形中加重了系統(tǒng)負(fù)擔(dān)。
· 另一方面,在基于傳統(tǒng)TCP/IP等網(wǎng)絡(luò)協(xié)議的通信模式下,CPU需要承擔(dān)大量的協(xié)議解析、包構(gòu)建及錯(cuò)誤處理等任務(wù),這不僅大量消耗了寶貴的計(jì)算資源,而且對(duì)通信延遲產(chǎn)生了不利影響,進(jìn)一步降低了整體的數(shù)據(jù)處理效率。
3.3.2 解決方案與原理
將RDMA技術(shù)應(yīng)用于Apache Spark,尤其是在Shuffle過(guò)程中,可以大幅度減輕網(wǎng)絡(luò)瓶頸帶來(lái)的影響。通過(guò)利用RDMA的高帶寬和低延遲特性,Spark的數(shù)據(jù)處理性能有望得到顯著的提升。
RDMA技術(shù)允許網(wǎng)絡(luò)設(shè)備直接訪(fǎng)問(wèn)應(yīng)用程序內(nèi)存空間,實(shí)現(xiàn)了內(nèi)核旁路(kernel bypass)。這意味著數(shù)據(jù)可以直接從發(fā)送方的內(nèi)存?zhèn)鬏數(shù)浇邮辗降膬?nèi)存,無(wú)需CPU介入,減少了傳輸過(guò)程中的延遲。如下圖所示。
3.2.3 優(yōu)勢(shì)與效果
在該方案中,Netty客戶(hù)端被RDMA客戶(hù)端所取代,并充分利用了RDMA單邊操作的特性。具體實(shí)現(xiàn)時(shí),磁盤(pán)數(shù)據(jù)通過(guò)內(nèi)存映射(MMAP)技術(shù)加載至用戶(hù)空間內(nèi)存,此后,客戶(hù)端利用RDMA能力在網(wǎng)絡(luò)層面執(zhí)行直接內(nèi)存訪(fǎng)問(wèn)操作。這一改進(jìn)避免了數(shù)據(jù)在操作系統(tǒng)內(nèi)核內(nèi)存和網(wǎng)絡(luò)接口間多次復(fù)制,從而提高了數(shù)據(jù)傳輸速度、降低了延遲并減輕了CPU負(fù)載。
數(shù)據(jù)傳輸效率提升:得益于RDMA的低延遲與高帶寬優(yōu)勢(shì),Spark中的數(shù)據(jù)處理速率顯著提高。這是因?yàn)镽DMA能夠?qū)崿F(xiàn)在網(wǎng)絡(luò)設(shè)備與應(yīng)用內(nèi)存之間的直接數(shù)據(jù)傳輸,減少了對(duì)CPU的依賴(lài),進(jìn)而降低了數(shù)據(jù)傳輸過(guò)程中的延時(shí)。
CPU占用率降低:RDMA的Kernel Bypass特性使得數(shù)據(jù)可以直接從內(nèi)存繞過(guò)內(nèi)核進(jìn)行傳輸,這不僅大大減少了CPU在數(shù)據(jù)傳輸階段的工作負(fù)擔(dān),而且提升了CPU資源的有效利用率,釋放出更多計(jì)算資源用于Spark的核心計(jì)算任務(wù)。
端到端處理時(shí)間縮短:對(duì)比傳統(tǒng)TCP傳輸方式,在多項(xiàng)性能測(cè)試中,采用RDMA的方案明顯縮短了端到端的數(shù)據(jù)處理時(shí)間,這意味著整體數(shù)據(jù)處理流程更加高效,能夠在更短的時(shí)間內(nèi)完成相同規(guī)模的計(jì)算任務(wù)。
Shuffle階段性能優(yōu)化:在Apache Spark框架中,Shuffle階段是一個(gè)關(guān)鍵且對(duì)性能影響較大的環(huán)節(jié)。借助RDMA減少數(shù)據(jù)傳輸和處理所需時(shí)間的優(yōu)勢(shì),有效地優(yōu)化了Shuffle階段的性能表現(xiàn),從而全面提升整個(gè)數(shù)據(jù)處理流程的效率。
大規(guī)模數(shù)據(jù)處理能力增強(qiáng):對(duì)于處理大規(guī)模數(shù)據(jù)集的場(chǎng)景,RDMA所提供的高效數(shù)據(jù)傳輸及低延遲特性尤為重要。它確保Spark能在更高效地處理大量數(shù)據(jù)的同時(shí),提高了大規(guī)模數(shù)據(jù)處理任務(wù)的可擴(kuò)展性和處理效率。
值得注意的是,在多種實(shí)際應(yīng)用場(chǎng)景下,使用RDMA通常能夠帶來(lái)大約10%左右的性能提升效果。然而,具體的加速效果會(huì)受到業(yè)務(wù)邏輯復(fù)雜性、數(shù)據(jù)處理工作負(fù)載特性的綜合影響,因此可能有所波動(dòng)。
四、加速效果
4.1端到端整體加速效果
在嚴(yán)格的單機(jī)單線(xiàn)程本地(local)模式測(cè)試環(huán)境下,未使用RDMA技術(shù),針對(duì)1TB規(guī)模的數(shù)據(jù)集,通過(guò)對(duì)比分析TPC-DS基準(zhǔn)測(cè)試SQL語(yǔ)句執(zhí)行時(shí)間,其中有5條語(yǔ)句的E2E(由driver端提交任務(wù)到driver接收輸出結(jié)果的時(shí)間)執(zhí)行時(shí)間得到了顯著提升,提升比例均超過(guò)2倍,最高可達(dá)到4.56倍提升。
4.2運(yùn)算符加速效果
進(jìn)一步聚焦于運(yùn)算符層面的性能改進(jìn),在對(duì)DPU加速方案與Spark原生運(yùn)算符進(jìn)行比較時(shí),觀(guān)察到運(yùn)算符執(zhí)行效率的最大提升比率達(dá)到9.97倍。這一顯著的加速效果主要源于DPU硬件層面的優(yōu)化設(shè)計(jì)和高效運(yùn)算能力。
4.3算子加速效果
在遵循TPC-DS基準(zhǔn)測(cè)試標(biāo)準(zhǔn)的前提下,相較于未經(jīng)優(yōu)化的原生Spark解決方案,本方案在關(guān)鍵算子性能方面實(shí)現(xiàn)了顯著提升。根據(jù)測(cè)試數(shù)據(jù)表明,F(xiàn)ilter算子的執(zhí)行效率提升了43倍,而哈希聚合算子的處理速率也提高了13倍之多。這一顯著性能飛躍的取得,主要?dú)w因于方案深入挖掘并有效利用了DPU所具備的強(qiáng)大計(jì)算能力和并行處理特性,從而大幅縮短了相關(guān)算子的執(zhí)行時(shí)間,并提升了整個(gè)系統(tǒng)的運(yùn)算效能。通過(guò)這種優(yōu)化措施,不僅確保了在復(fù)雜查詢(xún)和大數(shù)據(jù)處理任務(wù)中更高的響應(yīng)速度,同時(shí)也驗(yàn)證了結(jié)合現(xiàn)代硬件技術(shù)對(duì)Spark性能進(jìn)行深度優(yōu)化的有效性和可行性。
4.4 RDMA加速效果
在實(shí)際應(yīng)用環(huán)境中,RDMA(Remote Direct Memory Access)技術(shù)展現(xiàn)出顯著的性能提升效果。通過(guò)直接訪(fǎng)問(wèn)遠(yuǎn)程內(nèi)存而無(wú)需CPU過(guò)多介入,RDMA能夠極大地減少數(shù)據(jù)傳輸過(guò)程中的延遲和CPU占用率,在多個(gè)不同場(chǎng)景中實(shí)現(xiàn)至少10%以上的性能增長(zhǎng)。這一優(yōu)勢(shì)體現(xiàn)在網(wǎng)絡(luò)密集型操作中尤為明顯,如大規(guī)模分布式系統(tǒng)間的通信與數(shù)據(jù)交換。
4.5 壓縮解壓縮加速效果
基于目前HADOS-RACE已經(jīng)實(shí)現(xiàn)的Snappy壓縮解壓縮方案,制定了對(duì)應(yīng)的性能測(cè)試計(jì)劃。首先生成snappy測(cè)試數(shù)據(jù),使用基于CPU和DPU的Spark分別對(duì)數(shù)據(jù)進(jìn)行處理,記錄各自的Snappy壓縮解壓縮階段和Spark整體端到端的耗時(shí)和吞吐。執(zhí)行的測(cè)試語(yǔ)句為:select * from table where a1 is not null and a2 is not null(盡量減少中間的計(jì)算過(guò)程,突出Snappy壓縮解壓縮的過(guò)程)。
單獨(dú)分析Snappy壓縮解壓縮階段,基于CPU的Snappy解壓縮,吞吐量為300MB/s。而將解壓縮任務(wù)卸載到DPU后,DPU核內(nèi)計(jì)算的吞吐量可達(dá)到1585MB/s。可以看到,基于DPU進(jìn)行Snappy解壓縮,相比基于CPU進(jìn)行Snappy解壓縮,性能可提升約5倍。
基于CPU的Spark計(jì)算過(guò)程總體比基于DPU的Spark計(jì)算過(guò)程耗時(shí)減少了約50%。相當(dāng)于基于DPU的端到端執(zhí)行性能是基于CPU端到端性能的兩倍。詳細(xì)測(cè)試結(jié)果如下所示:
五、未來(lái)規(guī)劃
5.1 現(xiàn)有優(yōu)勢(shì)
性能方面,得益于DPU做算力卸載的高效性,相對(duì)于社區(qū)版本Spark具備較為明顯的優(yōu)勢(shì),尤其是單機(jī)場(chǎng)景下,該場(chǎng)景下由于更偏重于純算力,優(yōu)勢(shì)更加明顯。
資源方面,得益于更優(yōu)秀的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì),在內(nèi)存、IO和網(wǎng)絡(luò)資源使用上,都具備不同程度的優(yōu)勢(shì),特別是內(nèi)存資源上,較社區(qū)版本Spark優(yōu)勢(shì)明顯。
5.2 現(xiàn)有不足
· 集群場(chǎng)景下性能提升較單機(jī)場(chǎng)景減弱,網(wǎng)絡(luò)傳輸?shù)男阅軗p耗削弱了整體性能提升能力。
· 功能覆蓋上,目前主要圍繞TPC-DS場(chǎng)景以及一些客戶(hù)提出的業(yè)務(wù)場(chǎng)景,未來(lái)還需要覆蓋更多的業(yè)務(wù)場(chǎng)景。
5.3 未來(lái)規(guī)劃
· 優(yōu)化和完善現(xiàn)有架構(gòu),繼續(xù)完善基礎(chǔ)功能覆蓋。
· 未來(lái)計(jì)劃在加速純計(jì)算場(chǎng)景的同時(shí),也同步引入更多維度的加速方案(如存儲(chǔ)加速、網(wǎng)絡(luò)加速),提升集群模式下的加速性能。
· 除了加速Spark,也同步探索更多的加速場(chǎng)景,如實(shí)時(shí)大數(shù)據(jù)、AI等算法場(chǎng)景加速。