<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一次 Spark SQL 性能提升10倍的經(jīng)歷

          共 9106字,需瀏覽 19分鐘

           ·

          2021-01-05 12:53

          點(diǎn)擊上方藍(lán)色字體,選擇“設(shè)為星標(biāo)
          回復(fù)”資源“獲取更多資源

          大數(shù)據(jù)技術(shù)與架構(gòu)
          點(diǎn)擊右側(cè)關(guān)注,大數(shù)據(jù)開發(fā)領(lǐng)域最強(qiáng)公眾號(hào)!

          大數(shù)據(jù)真好玩
          點(diǎn)擊右側(cè)關(guān)注,大數(shù)據(jù)真好玩!

          1. 遇到了啥問題

          是醬紫的,簡(jiǎn)單來(lái)說(shuō):并發(fā)執(zhí)行 spark job 的時(shí)候,并發(fā)的提速很不明顯。類似于我們內(nèi)部有一個(gè)系統(tǒng)給分析師用,他們寫一些 sql,在我們的 spark cluster 上跑。隨著分析師越來(lái)越多,sql job 也越來(lái)越多,等待運(yùn)行的時(shí)間也越來(lái)越長(zhǎng),我們就在想怎么把 sql 運(yùn)行的時(shí)間加快一點(diǎn)。我們的整個(gè)架構(gòu)是 spark 1.6.1 on YARN 的,經(jīng)過(guò)分析一些 sql 發(fā)現(xiàn)其實(shí)大多數(shù)分析語(yǔ)句都是比較簡(jiǎn)單的統(tǒng)計(jì) sql,集群資源也還算多,一條簡(jiǎn)單的 sql 語(yǔ)句就把整個(gè)集群資源的坑占著略顯不合適,有點(diǎn)飛機(jī)馬達(dá)裝到拖拉機(jī)上的趕腳,所以第一步,我們想,支持 spark job 的并行運(yùn)行。
          ok,初步方案有了,我們就做了如下幾步改善工作:
          首先設(shè)置?spark.scheduler.mode?為?FAIR?模式
          首先?spark.scheduler.mode?有?FIFO,?FAIR?兩種模式,FIFO?是說(shuō)提交的job,都是順序執(zhí)行的,后提交的 job 一定要等之前提交的 job 完全執(zhí)行結(jié)束后才可以執(zhí)行;FAIR?是說(shuō),如果之前提交的 job 沒有用完集群資源的話,后提交的job可以即刻開始運(yùn)行。關(guān)于這點(diǎn)在官方文檔上有詳細(xì)的解釋:
          其次,我們生成了 10 個(gè) pool,所謂的 pool,可以理解為資源池,或者通道。你可以在提交 job 的時(shí)候指定提交到哪個(gè) pool 里面,可以簡(jiǎn)單的理解為我們把所有的集群資源分成 10 份,然后在提交 job 的時(shí)候指定在哪一份資源中運(yùn)行這個(gè) job。
          ?最后,我們?cè)谔峤?job 的時(shí)候指定提交到的 pool 名字,只需要在提交 job 之前設(shè)置一個(gè) sparkContext 的參數(shù)即可:?sc.setLocalProperty("spark.scheduler.pool", "your_pool_id")
          看似很簡(jiǎn)單,但能知道上面這些配置的也算是用 spark 比較熟練的人了吧,我迫不及待的測(cè)試了一下速度,發(fā)現(xiàn)了一個(gè)從古至今的大真理:理想很美好,現(xiàn)實(shí)很骨干啊。測(cè)試下來(lái),發(fā)現(xiàn)多個(gè) job 并行運(yùn)行的時(shí)間并沒有節(jié)省多少。

          2. 原因排查

          上面把問題說(shuō)得很清楚了:多 job 并行的時(shí)候,運(yùn)行速度并沒有明顯提升。但是原理上應(yīng)該不會(huì)如此,只要一個(gè) sql job 不需要全局所有集群資源,理論上來(lái)說(shuō)會(huì)有較大提升的。下面是一組簡(jiǎn)單的數(shù)據(jù)對(duì)比:
          雖然看到,并行計(jì)算后時(shí)間只需要之前的 50%,但是這里需要說(shuō)明一下,這個(gè)數(shù)據(jù)不夠穩(wěn)定的哦,比如說(shuō)偶爾會(huì)新增 10來(lái)秒 這樣子的。這里?暫且接受提升 50% 的速度這樣一個(gè)結(jié)論吧
          但是,理論上來(lái)說(shuō),還能提升更多,不滿足 50% 的提升效率,我們接著深度解讀 spark web ui 上的一些分析數(shù)據(jù),嘗試找找能否把速度再度提升一下。終于找到了核心原因,下面我就把整個(gè)排查的過(guò)程詳細(xì)記錄下來(lái):
          • 找一個(gè)花費(fèi)時(shí)間較長(zhǎng)的 job,進(jìn)去看看執(zhí)行的詳情,這里我們用 job id 為 796 的這個(gè) job

          • 發(fā)現(xiàn) job 796 有兩個(gè) stage,且有 99% 的時(shí)間都花在第一個(gè) stage 1590 上了,而且需要注意的是,這個(gè) stage 有 237.6mb 的數(shù)據(jù)讀取,有可能需要經(jīng)過(guò)網(wǎng)絡(luò)從其他 hdfs 節(jié)點(diǎn)讀過(guò)來(lái),難道跟網(wǎng)絡(luò) I/O 有關(guān)?繼續(xù)點(diǎn)進(jìn)去看看。

          • 進(jìn)來(lái)這個(gè) stage 內(nèi)部,似乎發(fā)現(xiàn)問題所在了,首先我們先關(guān)注下圖中標(biāo)記的幾個(gè)點(diǎn),可以總結(jié)出幾個(gè)點(diǎn):

            • 首先,該 stage 內(nèi)的所有任務(wù)在 executor 上真正執(zhí)行的時(shí)間【可以理解為 cpu time】是 2s

            • 其次,該 stage 內(nèi)任務(wù)執(zhí)行完成的時(shí)間是 1.1 m,大概是 66s,可以理解為【wall time】

            • 該 stage 內(nèi)所有的 task,schedule delay?的時(shí)間中位數(shù)是 0.5s,最大達(dá)到 1s【真正執(zhí)行的時(shí)間也才 2s 哦】

          • 該 stage 內(nèi)一共有 336 個(gè)task

          ?
          到這里,問題根源基本上已經(jīng)知道了,即 job 796 的大多數(shù)時(shí)間都被消耗在 stage 1590 的 336 個(gè)task 的 secheduler delay 上面了。

          3. 如何解決

          上面問題幾乎已經(jīng)明確了,現(xiàn)在就該看看腫么解決了。我當(dāng)時(shí)是這樣去考慮的:
          • 為什么 scheduler delay 會(huì)這么大

          因?yàn)橘Y源不夠,要解決這個(gè)問題,似乎唯一的辦法就是增加集群資源了。可是哥們,集群是你想加就能加的嗎?那可是要砸錢的呀?而且如果公司缺機(jī)器的話,想加集群資源也要經(jīng)過(guò) 申請(qǐng)->審批->采購(gòu)->分配->集群配置 大大小小幾個(gè)階段,說(shuō)不一定等你找到女朋友了都還沒搞定啊。
          當(dāng)時(shí)想著加資源這個(gè)方案短期不可取后,有那么幾分鐘是覺得有點(diǎn)燒腦的。我就靜靜的看著 web ui,心里在算,一個(gè) task 如果平均 scheduler delay 0.5s 的話,這 336 個(gè) task 就得 delay 118 秒,基本上都到 2 分鐘了。這 delay 的時(shí)間可真夠長(zhǎng)的啊,就在算這個(gè)數(shù)值的時(shí)候,突然想到這樣一個(gè)公式:total delay time = average delay time * task number。現(xiàn)在我們的問題是要解決 total delay time,那完全可以從兩方面去解決呀:
          • 降低 average delay time:目前來(lái)看似乎唯一的方法是砸錢加資源

          • 降低 task 數(shù):粗略來(lái)看,簡(jiǎn)單的降低 task 數(shù)的話,應(yīng)該是能減少 total delay time 的,但是如果task 數(shù)降低了,意味著每個(gè) task 需要處理的數(shù)據(jù)量就多了,那其他的時(shí)間應(yīng)該是會(huì)增加一些的,比如說(shuō)?Task Deserialization Time, Result Serialization Time, GC Time, Duration?等。減少 task 數(shù)究竟能不能提高整體運(yùn)行速度,似乎乍一看還真不好確定。

          反正砸錢加資源這個(gè)方案暫時(shí)是行不通的,要不就再仔細(xì)分析一下降低task數(shù)這個(gè)方案。這里我們?cè)谧屑?xì)參考一下下圖中這一列指標(biāo):

          我們用 75 分位的統(tǒng)計(jì)數(shù)據(jù)來(lái)做一個(gè)假設(shè):假設(shè)我們把每一個(gè) task 的數(shù)據(jù)量加 10 倍,那么預(yù)計(jì)的 task metrics 75 分位大概是一個(gè)什么樣的數(shù)值,假設(shè)這些指標(biāo)都是線性增長(zhǎng)的話:
          • Duration: 擴(kuò)大到 10 倍,14ms

          • Scheduler Delay: 這個(gè)指標(biāo)不用估計(jì)

          • Task Deserialization Time: 擴(kuò)大到 10 倍,6ms

          • GC Time: 擴(kuò)大到 10 倍,最多1ms

          • Result Serialization Time: 擴(kuò)大到 10 倍,最多1ms

          • Getting Result Time: 擴(kuò)大到 10 倍,最多1ms

          • Peak Execution Memory: 擴(kuò)大到 10 倍,最多 1b

          • Input Size / Records: 擴(kuò)大到 10 倍,918.8 KB * 2 / 2

          • Shuffle Write Size / Records 0: 擴(kuò)大到 10 倍,294.0 B * 2/ 20

          可以看到,這樣大概估計(jì)下來(lái),除去 Scheduler Delay 的時(shí)間,其實(shí)其他時(shí)間也沒消耗多少,都是毫秒級(jí)的,看起來(lái)應(yīng)該是完全可行的呀。
          正準(zhǔn)備這樣測(cè)試的時(shí)候,我忽然想到,為什么現(xiàn)在的 metrics 統(tǒng)計(jì)是這樣的結(jié)構(gòu)的啊,這么多 task?一般來(lái)說(shuō),一個(gè) task 對(duì)應(yīng)到 hdfs 上的一個(gè) parquet 文件【該項(xiàng)目中所有數(shù)據(jù)文件都是用 parquet 壓縮后存儲(chǔ)到 hdfs 上的】,難道是現(xiàn)在存在 hdfs 上的 parquet 文件個(gè)數(shù)過(guò)多,每個(gè)文件太小?突然有一種恍然大悟的感覺,趕緊看看現(xiàn)在 hdfs 上文件的結(jié)構(gòu),如下所示:


          @mac007:~/Desktop/dyes/git-mercury/mercury-computing$hadoop fs -ls -h hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ | cat -n | tail
          317 -rw-r--r-- 3 taotao hfmkt 1.3 M 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00310-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          318 -rw-r--r-- 3 taotao hfmkt 1.4 M 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00311-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          319 -rw-r--r-- 3 taotao hfmkt 2.9 M 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00312-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          320 -rw-r--r-- 3 taotao hfmkt 1.2 M 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00313-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          321 -rw-r--r-- 3 taotao hfmkt 1.9 M 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00314-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          322 -rw-r--r-- 3 taotao hfmkt 1.7 M 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00315-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          323 -rw-r--r-- 3 taotao hfmkt 899.4 K 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00316-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          324 -rw-r--r-- 3 taotao hfmkt 2.3 M 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00317-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          325 -rw-r--r-- 3 taotao hfmkt 1.0 M 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00318-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          326 -rw-r--r-- 3 taotao hfmkt 460.9 K 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00319-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet


          可以看到,現(xiàn)在有 300 多個(gè)文件【上面只是一部分,還有十幾個(gè)在另外一個(gè)文件夾里,一個(gè) sql 會(huì)統(tǒng)計(jì)兩個(gè)文件夾里的數(shù)據(jù)文件】,而且我仔細(xì)看了一下,每個(gè)文件大小最小的有很多 1kb 的,最大的有 2.9mb 的。難怪了,原來(lái)核心根源在這里。再結(jié)合上面關(guān)于 metrics 的分析,我心里大概確信了,只要把 parquet 文件的問題解決就行了,方法就是壓縮 parquet 文件個(gè)數(shù),控制每個(gè) parquet 文件的大小即可。方法確定了,那就干咯。

          4. 效果對(duì)比

          未來(lái)方便對(duì)比,我把 20161212 的數(shù)據(jù)文件處理了一下,保留 20161117 這天的數(shù)據(jù)文件【20161212 的數(shù)據(jù)文件整體上比 20161117 的數(shù)據(jù)文件要多 10%】,下面是對(duì)比結(jié)果:
          parquet 文件個(gè)數(shù)
          • 20161117 這天

          taotao@mac007:~/Desktop/dyes/git-mercury/mercury-computing$hadoop fs -ls -h hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_S* | cat -n | tail -n 5
          342 -rw-r--r-- 3 taotao hfmkt 1.7 M 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00315-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          343 -rw-r--r-- 3 taotao hfmkt 899.4 K 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00316-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          344 -rw-r--r-- 3 taotao hfmkt 2.3 M 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00317-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          345 -rw-r--r-- 3 taotao hfmkt 1.0 M 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00318-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          346 -rw-r--r-- 3 taotao hfmkt 460.9 K 2016-11-17 16:37 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161117/20161117_Transaction_SZ/part-r-00319-38d7cc53-60d2-40b3-a945-0cb5832f30de.gz.parquet
          • 20161212 這天

          taotao@mac007:~/Desktop/dyes/git-mercury/mercury-computing$hadoop fs -ls -h hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161212/20161212_Transaction_S* | cat -n | tail -n 5
          34 -rw-r--r-- 3 taotao hfmkt 19.2 M 2016-12-12 15:49 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161212/20161212_Transaction_SZ/part-r-00013-686bbce5-a7a1-4b5d-b25c-14cd9ddae283.gz.parquet
          35 -rw-r--r-- 3 taotao hfmkt 10.7 M 2016-12-12 15:49 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161212/20161212_Transaction_SZ/part-r-00014-686bbce5-a7a1-4b5d-b25c-14cd9ddae283.gz.parquet
          36 -rw-r--r-- 3 taotao hfmkt 26.0 M 2016-12-12 15:49 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161212/20161212_Transaction_SZ/part-r-00015-686bbce5-a7a1-4b5d-b25c-14cd9ddae283.gz.parquet
          37 -rw-r--r-- 3 taotao hfmkt 20.1 M 2016-12-12 15:49 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161212/20161212_Transaction_SZ/part-r-00016-686bbce5-a7a1-4b5d-b25c-14cd9ddae283.gz.parquet
          38 -rw-r--r-- 3 taotao hfmkt 8.7 M 2016-12-12 15:49 hdfs://hadoop-archive-cluster/hfmkt/level2/datayes/parquet/20161212/20161212_Transaction_SZ/part-r-00017-686bbce5-a7a1-4b5d-b25c-14cd9ddae283.gz.parquet


          100個(gè)job并發(fā)執(zhí)行時(shí)間
          • 20161117 這天:99s

          • 20161212 這天:16s

          Spark Web UI 上一個(gè) job 對(duì)比
          • 20161117 這天

          ?
          • 20161212 這天

          5. 總結(jié)

          首先,需要說(shuō)明的是,這次優(yōu)化應(yīng)該還有提升的空間,雖然優(yōu)化后整體從 204s 到 99s 再到 16s,提升了十倍多,確實(shí)很大,但是最后我們還是發(fā)現(xiàn) 16s 的情況下,scheduler delay 和 Task Deserialization Time 還是有占用了大部分時(shí)間,這里我覺得不能一味的在文件個(gè)數(shù)和大小上下功夫了。需要考慮到用戶場(chǎng)景來(lái)做一個(gè)權(quán)衡。所以越到后期的優(yōu)化,越考驗(yàn)產(chǎn)品功能的設(shè)計(jì),當(dāng)然這是后話了,就不在本文范圍內(nèi)討論。
          其次,這次優(yōu)化,從發(fā)現(xiàn)問題,追根溯源,到最后解決問題,大概花了 1 小時(shí),基本上還算不錯(cuò)。通過(guò)這次排查,還是真心感受到 spark 設(shè)計(jì)的完善,不得不說(shuō),作為一個(gè)開源項(xiàng)目,spark 最大的特點(diǎn),我覺得應(yīng)該是 spark 是由一幫非程序員設(shè)計(jì)實(shí)現(xiàn)的,而是一幫由程序員,架構(gòu)師,產(chǎn)品經(jīng)理組合起來(lái)一起干的,更像是一個(gè)產(chǎn)品,而不是一個(gè)開源項(xiàng)目。



          超全Spark性能優(yōu)化總結(jié)

          一次SparkSQL性能分析與優(yōu)化之旅及相關(guān)工具小結(jié)

          基于 Spark 技術(shù)快速構(gòu)建數(shù)倉(cāng)項(xiàng)目



          版權(quán)聲明:
          本文為大數(shù)據(jù)技術(shù)與架構(gòu)原創(chuàng)整理,轉(zhuǎn)載需作者授權(quán)。未經(jīng)作者允許轉(zhuǎn)載追究侵權(quán)責(zé)任。
          微信公眾號(hào)|import_bigdata
          編輯 |?《大數(shù)據(jù)技術(shù)與架構(gòu)》
          文章鏈接?https://blog.csdn.net/kisimple

          歡迎點(diǎn)贊+收藏+轉(zhuǎn)發(fā)朋友圈素質(zhì)三連


          文章不錯(cuò)?點(diǎn)個(gè)【在看】吧!??
          瀏覽 62
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人妻无码久久精品人妻成人 | 日日干夜夜撸 | 波多野吉衣中文字幕在线 | 亚洲另类调教 | 国产成人毛片18女人18精品 |