隨著各行各業(yè)的企業(yè)數(shù)據(jù)規(guī)模不斷增長(zhǎng),Apache Parquet 已經(jīng)成為了一種主流數(shù)據(jù)存儲(chǔ)格式。Apache Parquet 是一種列式存儲(chǔ)格式,專為高效的大規(guī)模數(shù)據(jù)處理而設(shè)計(jì)。它按列而非按行的方式組織數(shù)據(jù),這使得 Parquet 在查詢時(shí)僅讀取所需的列,而無(wú)需掃描整行數(shù)據(jù),即可實(shí)現(xiàn)高性能的查詢和分析。高效的數(shù)據(jù)布局使 Parquet 在現(xiàn)代分析生態(tài)系統(tǒng)中成為了受歡迎的選擇,尤其是在 Apache Spark 工作負(fù)載中。
適用于 Apache Spark 的 RAPIDS 加速器基于 cuDF 構(gòu)建,支持 Parquet 數(shù)據(jù)格式,可在 GPU 上加速讀取和寫入數(shù)據(jù)。對(duì)于許多輸入數(shù)據(jù)量達(dá)到 TB 級(jí)別的大規(guī)模 Spark 工作負(fù)載而言,高效的 Parquet 掃描對(duì)于實(shí)現(xiàn)良好的運(yùn)行時(shí)性能至關(guān)重要。
本文將討論如何緩解因較高的寄存器使用率導(dǎo)致的占用限制問(wèn)題,并分享基準(zhǔn)測(cè)試結(jié)果。
Apache Parquet 數(shù)據(jù)格式
Parquet 文件格式采用列式存儲(chǔ)結(jié)構(gòu),通過(guò)將列線程塊組裝成行組來(lái)實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)。其中元數(shù)據(jù)不同于數(shù)據(jù),可以根據(jù)需要拆分到多個(gè)文件中(如圖 1 所示)。

圖 1. Parquet 文件格式(來(lái)源:文件格式)
Parquet 格式支持多種數(shù)據(jù)類型。元數(shù)據(jù)規(guī)定了該如何解釋這些數(shù)據(jù)類型,從而能夠支持更復(fù)雜的邏輯類型表示,比如時(shí)間戳、字符串、小數(shù)等等。
元數(shù)據(jù)還可以用于說(shuō)明更復(fù)雜的結(jié)構(gòu),如嵌套類型和列表。數(shù)據(jù)可以用多種不同的格式進(jìn)行編碼,例如普通值、字典編碼、行程長(zhǎng)度編碼、位打包(bit-packing)等等。

GPU 上 Parquet 的占用限制
在適用于 Apache Spark 的 RAPIDS 加速器之前,Parquet 掃描是通過(guò)一個(gè)單一 cuDF 內(nèi)核實(shí)現(xiàn)的,它在一組處理代碼中支持所有 Parquet 列類型。
使用 Parquet 數(shù)據(jù)的客戶越來(lái)越多地在 GPU 上采用 Spark。鑒于 Parquet 掃描對(duì)性能有關(guān)鍵影響,人們投入了更多時(shí)間來(lái)了解其性能特征。以下是幾個(gè)會(huì)影響內(nèi)核運(yùn)行效率的常見因素:
流式多處理器(SM):GPU 的主要處理單元,負(fù)責(zé)執(zhí)行計(jì)算任務(wù)。
共享內(nèi)存:GPU 上集成的內(nèi)存,按線程塊分配,同一線程塊中的所有線程都可以訪問(wèn)相同的共享內(nèi)存。
寄存器:GPU 上集成的快速內(nèi)存,存儲(chǔ)單個(gè)線程使用的信息,用于流式多處理器執(zhí)行的計(jì)算操作。
我們?cè)诜治?Parquet 掃描時(shí)發(fā)現(xiàn),由于遇到寄存器限制,GPU 的總體占用率低于預(yù)期。寄存器的使用情況,取決于 CUDA 編譯器如何根據(jù)內(nèi)核邏輯和數(shù)據(jù)管理來(lái)生成代碼。
對(duì)于 Parquet 單內(nèi)核而言,支持所有列類型的復(fù)雜性導(dǎo)致了內(nèi)核龐大且復(fù)雜,其共享內(nèi)存和寄存器使用率都很高。盡管單一內(nèi)核可能將代碼整合在了一起,但其復(fù)雜性限制了可能的優(yōu)化類型,并在大規(guī)模應(yīng)用時(shí)導(dǎo)致了性能受限。

圖 2. GPU 上的 Parquet 單內(nèi)核
圖 2 展示了 GPU 上的 Parquet 數(shù)據(jù)處理循環(huán)。每個(gè)模塊都是大量復(fù)雜的內(nèi)核代碼,可能都有各自的共享內(nèi)存需求。許多線程塊依賴于數(shù)據(jù)類型,這導(dǎo)致加載到內(nèi)存中的內(nèi)核變得極為臃腫。
具體而言,其中一個(gè)限制在于 Parquet 塊在線程束(warp)內(nèi)的解碼方式。線程束在處理自身線程塊前,需要按順序等待先前調(diào)度的線程束完成操作。這種機(jī)制雖然允許不同線程束并行處理解碼過(guò)程的不同階段,但卻造成了 GPU 上引入了低效的任務(wù)依賴關(guān)系,導(dǎo)致效率低下。
轉(zhuǎn)向采用塊級(jí)解碼算法對(duì)提升性能至關(guān)重要,但由于其增加了數(shù)據(jù)共享和同步的復(fù)雜性,可能會(huì)進(jìn)一步增加寄存器數(shù)量并限制占用率。
cuDF 中的 Parquet 微內(nèi)核
為了緩解因寄存器使用率較高而導(dǎo)致的占用受限問(wèn)題,最初嘗試的方法是為 Parquet 中的預(yù)處理列表類型數(shù)據(jù)創(chuàng)建一個(gè)較小的內(nèi)核。從單內(nèi)核中分離出一段代碼,形成一個(gè)獨(dú)立的內(nèi)核,結(jié)果令人振奮——基準(zhǔn)測(cè)試的整體結(jié)果顯示運(yùn)行時(shí)間更快,并且 GPU 跟蹤數(shù)據(jù)也表明占用率有所提高。
隨后對(duì)不同的列類型也采用了相同的方法。針對(duì)各種數(shù)據(jù)類型的微內(nèi)核使用 C++ 模板來(lái)實(shí)現(xiàn)功能復(fù)用,這簡(jiǎn)化了每種類型的代碼維護(hù)和調(diào)試工作。

圖 3. GPU 上的 Parquet 微內(nèi)核方法
Parquet 微內(nèi)核方法充分利用編譯時(shí)優(yōu)化,僅執(zhí)行處理給定類型所需的代碼路徑。與包含所有可能代碼路徑的單一內(nèi)核不同,該方法可以生成許多單獨(dú)的微內(nèi)核,而每個(gè)微內(nèi)核僅包含該路徑所需的代碼。
這一過(guò)程可以通過(guò)在編譯時(shí)使用 if constexpr 來(lái)實(shí)現(xiàn)。這樣一來(lái),使得代碼保持自然可讀的結(jié)構(gòu),但不會(huì)包含特定數(shù)據(jù)屬性組合(字符串或固定寬度、有列表或無(wú)列表等)永遠(yuǎn)不會(huì)執(zhí)行的代碼路徑。
以下是一個(gè)處理固定寬度類型列的簡(jiǎn)單示例??梢钥吹?,在新的微內(nèi)核方法中,大部分不必要的處理步驟都被跳過(guò)了。這種數(shù)據(jù)類型只需要復(fù)制數(shù)據(jù)。

圖 4.固定寬度類型的 Parquet 微內(nèi)核方法
為了解決線程束之間的瓶頸問(wèn)題,新的微內(nèi)核使每個(gè)步驟都能處理整個(gè)線程塊,使得線程束可以更高效地獨(dú)立處理數(shù)據(jù)。這對(duì)于字符串處理尤為重要,它使得 GPU 上包含 128 個(gè)線程的完整線程塊都能用于復(fù)制字符串,而之前的實(shí)現(xiàn)方式僅使用一個(gè)線程束來(lái)復(fù)制字符串。
在使用了一塊具有 24 GB GPU 顯存的 NVIDIA RTX A5000 顯卡的本地基準(zhǔn)測(cè)試中,設(shè)備緩沖區(qū)中預(yù)先加載了 512MB 使用 Snappy 壓縮的 Parquet 數(shù)據(jù)。為了測(cè)試分塊讀取,每次讀取 500-KB 的塊。測(cè)試數(shù)據(jù)包含以下幾種變化:
基數(shù)為 0 和 1000
運(yùn)行長(zhǎng)度為 1 和 32
1% 的空值
如果數(shù)據(jù)有重復(fù),則使用自適應(yīng)字典編碼
圖 5 展示了在 GPU 上使用新的微內(nèi)核方法后,不同 Parquet 列類型在吞吐量方面的提升情況。

圖 5. GPU 上使用 Parquet 微內(nèi)核方法的吞吐量提升
對(duì)列表列分塊讀取的優(yōu)化還使 500-KB 讀取的吞吐量提高了 117%。
在 GPU 上開始使用 Apache Spark
Parquet 是一種廣泛用于大數(shù)據(jù)處理的關(guān)鍵數(shù)據(jù)格式。通過(guò)使用 cuDF 中經(jīng)過(guò)優(yōu)化的微內(nèi)核,GPU 可以加速在 Apache Spark 中掃描 Parquet 數(shù)據(jù)的進(jìn)程。
企業(yè)可以利用適用于 Apache Spark 的 RAPIDS 加速器,將 Apache Spark 工作負(fù)載無(wú)縫遷移到 NVIDIA GPU。適用于 Apache Spark 的 RAPIDS 加速器結(jié)合了 RAPIDS cuDF 庫(kù)的強(qiáng)大功能和 Spark 分布式計(jì)算框架的規(guī)模,利用 GPU 加速處理。通過(guò)使用適用于 Apache Spark 的 RAPIDS 加速器插件 JAR 文件啟動(dòng) Spark,無(wú)需更改代碼即可在 GPU 上運(yùn)行現(xiàn)有的 Apache Spark 應(yīng)用程序。
-
加速器
+關(guān)注
關(guān)注
2文章
839瀏覽量
40097 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7335瀏覽量
94754 -
gpu
+關(guān)注
關(guān)注
28文章
5194瀏覽量
135425
原文標(biāo)題:使用 GPU 加速 Apache Spark 上的 Apache Parquet 掃描
文章出處:【微信號(hào):NVIDIA-Enterprise,微信公眾號(hào):NVIDIA英偉達(dá)企業(yè)解決方案】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
RDMA技術(shù)在Apache Spark中的應(yīng)用
《CST Studio Suite 2024 GPU加速計(jì)算指南》
如何使用Apache Spark 2.0
Apache Spark 1.6預(yù)覽版新特性展示
Apache Spark上的分布式機(jī)器學(xué)習(xí)的介紹
NVIDIA為全球領(lǐng)先的數(shù)據(jù)分析平臺(tái)Apache Spark提速
Apache Spark 3.2有哪些新特性
NVIDIA RAPIDS加速器可將工作分配集群中各節(jié)點(diǎn)
利用Apache Spark和RAPIDS Apache加速Spark實(shí)踐
使用Apache Spark和NVIDIA GPU加速深度學(xué)習(xí)
NVIDIA TensorRT與Apache Beam SDK的集成
NVIDIA加速的Apache Spark助力企業(yè)節(jié)省大量成本
使用NVIDIA GPU加速Apache Spark中Parquet數(shù)據(jù)掃描
評(píng)論