溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的

發(fā)布時(shí)間:2021-12-17 09:06:16 來(lái)源:億速云 閱讀:307 作者:柒染 欄目:大數(shù)據(jù)

這篇文章給大家介紹EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

引言

隨著大數(shù)據(jù)技術(shù)架構(gòu)的演進(jìn),存儲(chǔ)與計(jì)算分離的架構(gòu)能更好的滿足用戶對(duì)降低數(shù)據(jù)存儲(chǔ)成本,按需調(diào)度計(jì)算資源的訴求,正在成為越來(lái)越多人的選擇。相較 HDFS,數(shù)據(jù)存儲(chǔ)在對(duì)象存儲(chǔ)上可以節(jié)約存儲(chǔ)成本,但與此同時(shí),對(duì)象存儲(chǔ)對(duì)海量文件的寫性能也會(huì)差很多。

MapReduce(EMR) 是騰訊云的一個(gè)云端托管的彈性開(kāi)源泛 Hadoop 服務(wù),支持 Spark、Hbase、Presto、Flink、Druid 等大數(shù)據(jù)框架。

近期,在支持一位 EMR 客戶時(shí),遇到典型的存儲(chǔ)計(jì)算分離應(yīng)用場(chǎng)景??蛻羰褂昧?EMR 中的 Spark 組件作為計(jì)算引擎,數(shù)據(jù)存儲(chǔ)在對(duì)象存儲(chǔ)上。在幫助客戶技術(shù)調(diào)優(yōu)過(guò)程中,發(fā)現(xiàn)了 Spark 在海量文件場(chǎng)景下寫入性能比較低,影響了架構(gòu)的整體性能表現(xiàn)。

在深入分析和優(yōu)化后,我們最終將寫入性能大幅提升,特別是將寫入對(duì)象存儲(chǔ)的性能提升了 10 倍以上,加速了業(yè)務(wù)處理,獲得了客戶好評(píng)。

下面將介紹在存儲(chǔ)計(jì)算分離架構(gòu)中, EMR Spark 計(jì)算引擎如何提升在海量文件場(chǎng)景下的寫性能。

一、問(wèn)題背景

Apache Spark 是專為大規(guī)模數(shù)據(jù)處理而設(shè)計(jì)的快速通用的計(jì)算引擎,可用來(lái)構(gòu)建大型的、低延遲的數(shù)據(jù)分析應(yīng)用程序。Spark 是 UC Berkeley AMP lab (加州大學(xué)伯克利分校的 AMP 實(shí)驗(yàn)室)所開(kāi)源的類 Hadoop MapReduce 的通用并行框架,Spark 擁有 Hadoop MapReduce 所具有的優(yōu)點(diǎn)。

與 Hadoop 不同,Spark 和 Scala 能夠緊密集成,其中的 Scala 可以像操作本地集合對(duì)象一樣輕松地操作分布式數(shù)據(jù)集。盡管創(chuàng)建 Spark 是為了支持分布式數(shù)據(jù)集上的迭代作業(yè),但是實(shí)際上它是對(duì) Hadoop 的補(bǔ)充,可以在 Hadoop 文件系統(tǒng)中并行運(yùn)行,也可以運(yùn)行在云存儲(chǔ)之上。

在這次技術(shù)調(diào)優(yōu)過(guò)程中,我們研究的計(jì)算引擎是 EMR 產(chǎn)品中的 Spark 組件,由于其優(yōu)異的性能等優(yōu)點(diǎn),也成為越來(lái)越多的客戶在大數(shù)據(jù)計(jì)算引擎的選擇。

存儲(chǔ)上,客戶選擇的是對(duì)象存儲(chǔ)。在數(shù)據(jù)存儲(chǔ)方面,對(duì)象存儲(chǔ)擁有可靠,可擴(kuò)展和更低成本等特性,相比 Hadoop 文件系統(tǒng) HDFS,是更優(yōu)的低成本存儲(chǔ)方式。海量的溫冷數(shù)據(jù)更適合放到對(duì)象存儲(chǔ)上,以降低成本。

在 Hadoop 的生態(tài)中,原生的 HDFS 存儲(chǔ)也是很多場(chǎng)景下必不可少的存儲(chǔ)選擇,所以我們也在下文加入了與 HDFS 的存儲(chǔ)性能對(duì)比。

回到我們想解決的問(wèn)題中來(lái),先來(lái)看一組測(cè)試數(shù)據(jù),基于 Spark-2.x 引擎,使用 SparkSQL 分別對(duì) HDFS、對(duì)象存儲(chǔ)寫入 5000 文件,分別統(tǒng)計(jì)執(zhí)行時(shí)長(zhǎng):

EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的

從測(cè)試結(jié)果可以看出,寫入對(duì)象存儲(chǔ)耗時(shí)是寫入 HDFS 的 29 倍,寫入對(duì)象存儲(chǔ)的性能要比寫入 HDFS 要差很多。而我們觀察數(shù)據(jù)寫入過(guò)程,發(fā)現(xiàn)網(wǎng)絡(luò) IO 并不是瓶頸,所以需要深入剖析一下計(jì)算引擎數(shù)據(jù)輸出的具體過(guò)程。

二、Spark數(shù)據(jù)輸出過(guò)程剖析

1. Spark數(shù)據(jù)流

先通過(guò)下圖理解一下 Spark 作業(yè)執(zhí)行過(guò)程中數(shù)據(jù)流轉(zhuǎn)的主要過(guò)程:

EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的

首先,每個(gè) task 會(huì)將結(jié)果數(shù)據(jù)寫入底層文件系統(tǒng)的臨時(shí)目錄 _temporary/task_[id],目錄結(jié)果示意圖如下所示:

EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的

到此為止,executor 上的 task 工作其實(shí)已經(jīng)結(jié)束,接下來(lái)將交由 driver,將這些結(jié)果數(shù)據(jù)文件 move 到 hive 表最終所在的 location 目錄下,共分三步操作:

第一步,調(diào)用 OutputCommiter 的 commitJob 方法做臨時(shí)文件的轉(zhuǎn)存和合并:

EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的

通過(guò)上面示意圖可以看到,commitJob 會(huì)將 task_[id] 子目錄下的所有數(shù)據(jù)文件 merge 到了上層目錄 ext-10000。

接下來(lái)如果是 overwrite 覆蓋寫數(shù)據(jù)模式,會(huì)先將表或分區(qū)中已有的數(shù)據(jù)移動(dòng)到 trash 回收站。

在完成上述操作后,會(huì)將第一步中合并好的數(shù)據(jù)文件,move 到 hive 表的 location,到此為止,所有數(shù)據(jù)操作完成。

2. 定位分析根因

有了上面對(duì) Spark 數(shù)據(jù)流的分析,現(xiàn)在需要定位性能瓶頸在 driver 端還是 executor 端?觀察作業(yè)在 executor 上的耗時(shí):

EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的

EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的

發(fā)現(xiàn)作業(yè)在 executor 端執(zhí)行時(shí)長(zhǎng)差異不大,而總耗時(shí)卻差異卻非常大, 這說(shuō)明作業(yè)主要耗時(shí)在 driver 端。

在 driver 端有 commitJob、trashFiles、moveFiles 三個(gè)操作階段,具體是在 driver 的哪些階段耗時(shí)比較長(zhǎng)呢?

我們通過(guò) spark-ui 觀察 Thread dump (這里通過(guò)手動(dòng)刷新 spark-ui 或者登錄 driver 節(jié)點(diǎn)使用 jstack 命令查看線程堆棧信息),發(fā)現(xiàn)這三個(gè)階段都比較慢, 下面我們來(lái)分析這三部分的源碼。

EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的 

EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的

EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的

3. 源碼分析

(1)JobCommit階段

Spark 使用的是 Hadoop 的 FileOutputCommitter 來(lái)處理文件合并操作, Hadoop 2.x 默認(rèn)使用 mapreduce.fileoutputcommitter.algorithm.version=1,使用單線程 for 循環(huán)去遍歷所有 task 子目錄,然后做 merge path 操作,顯然在輸出文件很多情況下,這部分操作會(huì)非常耗時(shí)。

特別是對(duì)對(duì)象存儲(chǔ)來(lái)說(shuō),rename 操作并不僅僅是修改元數(shù)據(jù),還需要去 copy 數(shù)據(jù)到新文件。

(2)TrashFiles階段

trashFiles 操作是單線程 for 循環(huán)來(lái)將文件 move 到文件回收站,如果需要被覆蓋寫的數(shù)據(jù)比較多,這步操作會(huì)非常慢。

(3)MoveFiles階段

與前面問(wèn)題類似,在 moveFiles 階段也是采用了單線程 for 循環(huán)方式來(lái) move 文件。

4. 問(wèn)題小結(jié)

  • Spark 引擎寫海量文件性能瓶頸在Driver端;

  • 在 Driver 的 CommitJob、TrashFiles、MoveFiles 三個(gè)階段執(zhí)行耗時(shí)都比較長(zhǎng);

  • 三個(gè)階段耗時(shí)長(zhǎng)的原因都是因?yàn)閱尉€程循環(huán)挨個(gè)處理文件;

  • 對(duì)象存儲(chǔ)的 rename 性能需要拷貝數(shù)據(jù),性能較差,導(dǎo)致寫海量文件時(shí)耗時(shí)特別長(zhǎng)。 

三、優(yōu)化結(jié)果

可以看到社區(qū)版本大數(shù)據(jù)計(jì)算引擎在處理對(duì)象存儲(chǔ)的訪問(wèn)上還在一定的性能問(wèn)題,主要原因是大多數(shù)數(shù)據(jù)平臺(tái)都是基于 HDFS 存儲(chǔ),而 HDFS 對(duì)文件的 rename 只需要在 namenode 上修改元數(shù)據(jù),這個(gè)操作是非??斓模蝗菀着龅叫阅芷款i。

而目前數(shù)據(jù)上云、存算分離是企業(yè)降低成本的重要考量,所以我們分別嘗試將 commitJob、trashFiles、moveFile 代碼修改成多線程并行處理文件,提升對(duì)文件寫操作性能。

基于同樣的基準(zhǔn)測(cè)試,使用 SparkSQL 分別對(duì) HDFS、對(duì)象存儲(chǔ)寫入 5000 個(gè)文件,我們得到了優(yōu)化后的結(jié)果如下圖所示:

EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的

最終寫 HDFS 性能提升 41%,寫對(duì)象存儲(chǔ)性能提升 1100% !

關(guān)于EMR Spark引擎是如何做到在存算分離下寫性能提升10倍以上的就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI