久久精品国产亚洲高清|精品日韩中文乱码在线|亚洲va中文字幕无码久|伊人久久综合狼伊人久久|亚洲不卡av不卡一区二区|精品久久久久久久蜜臀AV|国产精品19久久久久久不卡|国产男女猛烈视频在线观看麻豆

千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

手機(jī)站
千鋒教育

千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

千鋒教育

掃一掃進(jìn)入千鋒手機(jī)站

領(lǐng)取全套視頻
千鋒教育

關(guān)注千鋒學(xué)習(xí)站小程序
隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

當(dāng)前位置:首頁(yè)  >  技術(shù)干貨  > Spark 數(shù)據(jù)傾斜調(diào)優(yōu)10策(三)

Spark 數(shù)據(jù)傾斜調(diào)優(yōu)10策(三)

來(lái)源:千鋒教育
發(fā)布人:wjy
時(shí)間: 2022-06-22 17:45:00 1655891100

  三、 數(shù)據(jù)傾斜解決方案

  3.1 Hive ETL處理

  3.1.1 適用場(chǎng)景

  導(dǎo)致數(shù)據(jù)傾斜的是 Hive 表。如果該 Hive 表中的數(shù)據(jù)本身很不均勻(比如某個(gè) key 對(duì)應(yīng)了 100 萬(wàn)數(shù) 據(jù),其他 key 才對(duì)應(yīng)了 10 條數(shù)據(jù)),而且業(yè)務(wù)場(chǎng)景需要頻繁使用 Spark 對(duì) Hive 表執(zhí)行某個(gè)分析操 作,那么比較適合使用這種技術(shù)方案

  3.1.2 實(shí)現(xiàn)思路

  此時(shí)可以評(píng)估一下,是否可以通過(guò)Hive來(lái)進(jìn)行數(shù)據(jù)預(yù)處理(即通過(guò) Hive ETL 預(yù)先對(duì)數(shù)據(jù)按照 key 進(jìn)行 聚合,或者是預(yù)先和其他表進(jìn)行join),然后在 Spark 作業(yè)中針對(duì)的數(shù)據(jù)源就不是原來(lái)的 Hive 表了, 而是預(yù)處理后的Hive表。此時(shí)由于數(shù)據(jù)已經(jīng)預(yù)先進(jìn)行過(guò)聚合或join操作了,那么在 Spark 作業(yè)中也就不 需要使用原先的 shuffle 類算子執(zhí)行這類操作了。

  3.1.3 實(shí)現(xiàn)原理

  這種方案從根源上解決了數(shù)據(jù)傾斜,因?yàn)閺氐妆苊饬嗽赟park中執(zhí)行shuffle類算子,那么肯定就不會(huì)有 數(shù)據(jù)傾斜的問(wèn)題了。但是這里也要提醒一下大家,這種方式屬于治標(biāo)不治本。因?yàn)楫吘箶?shù)據(jù)本身就存在 分布不均勻的問(wèn)題,所以Hive ETL中進(jìn)行g(shù)roup by或者join等shuffle操作時(shí),還是會(huì)出現(xiàn)數(shù)據(jù)傾斜,導(dǎo) 致Hive ETL的速度很慢。我們只是把數(shù)據(jù)傾斜的發(fā)生提前到了Hive ETL中,避免Spark程序發(fā)生數(shù)據(jù)傾 斜而已。

  3.1.4 方案優(yōu)缺點(diǎn)

  * 優(yōu)點(diǎn): 實(shí)現(xiàn)起來(lái)簡(jiǎn)單便捷,效果還非常好,完全規(guī)避掉了數(shù)據(jù)傾斜,Spark作業(yè)的性能會(huì)大幅度提升。

  * 缺點(diǎn):治標(biāo)不治本,Hive ETL中還是會(huì)發(fā)生數(shù)據(jù)傾斜。

  3.1.5 企業(yè)最佳實(shí)踐

  * 在一些 Java 系統(tǒng)與 Spark 結(jié)合使用的項(xiàng)目中,會(huì)出現(xiàn) Java 代碼頻繁調(diào)用 Spark 作業(yè)的場(chǎng)景,而且對(duì) Spark 作業(yè)的執(zhí)行性能要求很高,就比較適合使用這種方案。將數(shù)據(jù)傾斜提前到上游的 Hive ETL,每天 僅執(zhí)行一次,只有那一次是比較慢的,而之后每次 Java 調(diào)用 Spark作業(yè)時(shí),執(zhí)行速度都會(huì)很快,能夠 提供更好的用戶體驗(yàn)。

  * 在美團(tuán)·點(diǎn)評(píng)的交互式用戶行為分析系統(tǒng)中使用了這種方案,該系統(tǒng)主要是允許用戶通過(guò) Java Web 系統(tǒng) 提交數(shù)據(jù)分析統(tǒng)計(jì)任務(wù),后端通過(guò)Java 提交 Spark作業(yè)進(jìn)行數(shù)據(jù)分析統(tǒng)計(jì)。要求 Spark 作業(yè)速度必須要 快,盡量在10 分鐘以內(nèi),否則速度太慢,用戶體驗(yàn)會(huì)很差。所以我們將有些 Spark 作業(yè)的shuffle操作 提前到了Hive ETL中,從而讓 Spark 直接使用預(yù)處理的 Hive 中間表,盡可能地減少 Spark 的 shuffle操 作,大幅度提升了性能,將部分作業(yè)的性能提升了6倍以上。

  3.2 調(diào)整shuffle操作的并行度

  3.2.1 適用場(chǎng)景

  大量不同的Key被分配到了相同的Task造成該Task數(shù)據(jù)量過(guò)大。

  如果我們必須要對(duì)數(shù)據(jù)傾斜迎難而上,那么建議優(yōu)先使用這種方案,因?yàn)檫@是處理數(shù)據(jù)傾斜最簡(jiǎn)單的一 種方案。但是也是一種屬于碰運(yùn)氣的方案。因?yàn)檫@種方案,并不能讓你一定解決數(shù)據(jù)傾斜,甚至有可能 加重。那當(dāng)然,總歸,你會(huì)調(diào)整到一個(gè)合適的并行度是能解決的。前提是這種方案適用于 Hash散列的 分區(qū)方式。湊巧的是,各種分布式計(jì)算引擎,比如MapReduce,Spark 等默認(rèn)都是使用 Hash散列的方 式來(lái)進(jìn)行數(shù)據(jù)分區(qū)。

  Spark 在做 Shuffle 時(shí),默認(rèn)使用 HashPartitioner(非Hash Shuffle)對(duì)數(shù)據(jù)進(jìn)行分區(qū)。如果并行度設(shè) 置的不合適,可能造成大量不相同的 Key 對(duì)應(yīng)的數(shù)據(jù)被分配到了同一個(gè) Task 上,造成該 Task 所處理 的數(shù)據(jù)遠(yuǎn)大于其它 Task,從而造成數(shù)據(jù)傾斜。

  如果調(diào)整 Shuffle 時(shí)的并行度,使得原本被分配到同一 Task 的不同 Key 發(fā)配到不同 Task 上處理,則可 降低原 Task 所需處理的數(shù)據(jù)量,從而緩解數(shù)據(jù)傾斜問(wèn)題造成的短板效應(yīng)。

  3.2.2 實(shí)現(xiàn)思路

  在對(duì) RDD 執(zhí)行 Shuffle 算子時(shí),給 Shuffle 算子傳入一個(gè)參數(shù),比如 reduceByKey(1000),該參數(shù)就 設(shè)置了這個(gè) shuffle 算子執(zhí)行時(shí)shuffle read task 的數(shù)量。對(duì)于 Spark SQL 中的 Shuffle 類語(yǔ)句,比如 group by、join 等,需要設(shè)置一個(gè)參數(shù),即 spark.sql.shuffle.partitions,該參數(shù)代表了 shuffle readTask 的并行度,該值默認(rèn)是 200,對(duì)于很多場(chǎng)景來(lái)說(shuō)都有點(diǎn)過(guò)小。

  3.2.3 實(shí)現(xiàn)原理

  增加 shuffle read task 的數(shù)量,可以讓原本分配給一個(gè) task 的多個(gè) key 分配給多個(gè) task,從而讓每個(gè) task 處理比原來(lái)更少的數(shù)據(jù)。舉例來(lái)說(shuō),如果原本有 5 個(gè)key,每個(gè) key 對(duì)應(yīng) 10 條數(shù)據(jù),這 5 個(gè) key 都是分配給一個(gè) task 的,那么這個(gè) task 就要處理 50 條數(shù)據(jù)。而增加了 shuffle read task 以后,每個(gè) task 就分配到一個(gè) key,即每個(gè) task 就處理 10 條數(shù)據(jù),那么自然每個(gè) task 的執(zhí)行時(shí)間都會(huì)變短了。 具體原理如下圖所示。

  一句話總結(jié):調(diào)整并行度分散同一個(gè) Task的不同 Key,之前由于運(yùn)氣比較差,多個(gè)數(shù)據(jù)比較多的 key 都分布式在同一個(gè) Task 上,如果調(diào)整了并行度,極大可能會(huì)讓這些 key 分布式到不同的 Task,有效緩 解數(shù)據(jù)傾斜。

01

 

  3.2.4 方案優(yōu)缺點(diǎn)

  * 優(yōu)點(diǎn): 實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單,可以有效緩解和減輕數(shù)據(jù)傾斜的影響。實(shí)現(xiàn)簡(jiǎn)單,可在需要Shuffle的操作算子上直接設(shè) 置并行度或者使用spark.default.parallelism設(shè)置。如果是Spark SQL,還可通過(guò)SET spark.sql.shuffle.partitions=[num_tasks]設(shè)置并行度??捎米钚〉拇鷥r(jià)解決問(wèn)題。一般如果出現(xiàn) 數(shù)據(jù)傾斜,都可以通過(guò)這種方法先試驗(yàn)幾次,如果問(wèn)題未解決,再嘗試其它方法。

  * 缺點(diǎn):只是緩解了數(shù)據(jù)傾斜而已,沒(méi)有徹底根除問(wèn)題,根據(jù)實(shí)踐經(jīng)驗(yàn)來(lái)看,其效果有限。適用場(chǎng)景少,只能將分配到 同一Task的不同Key分散開(kāi),但對(duì)于同一Key傾斜嚴(yán)重的情況該方法并不適用。并且該方法一般只能緩解數(shù)據(jù) 傾斜,沒(méi)有徹底消除問(wèn)題。從實(shí)踐經(jīng)驗(yàn)來(lái)看,其效果一般。

  3.2.5 企業(yè)最佳實(shí)踐

  * 該方案通常無(wú)法徹底解決數(shù)據(jù)傾斜,因?yàn)槿绻霈F(xiàn)一些極端情況,比如某個(gè)key對(duì)應(yīng)的數(shù)據(jù)量有100萬(wàn), 那么無(wú)論你的task數(shù)量增加到多少,這個(gè)對(duì)應(yīng)著100萬(wàn)數(shù)據(jù)的key肯定還是會(huì)分配到一個(gè)task中去處理, 因此注定還是會(huì)發(fā)生數(shù)據(jù)傾斜的。所以這種方案只能說(shuō)是在發(fā)現(xiàn)數(shù)據(jù)傾斜時(shí)嘗試使用的第一種手段,嘗 試去用嘴簡(jiǎn)單的方法緩解數(shù)據(jù)傾斜而已,或者是和其他方案結(jié)合起來(lái)使用

  3.3 過(guò)濾少數(shù)導(dǎo)致傾斜的key

  3.3.1 適用場(chǎng)景

  如果發(fā)現(xiàn)導(dǎo)致傾斜的 key 就少數(shù)幾個(gè),而且對(duì)計(jì)算本身的影響并不大的話,那么很適合使用這種方案。 比如 99% 的 key 就對(duì)應(yīng) 10 條數(shù)據(jù),但是只有一個(gè) key 對(duì)應(yīng)了 100 萬(wàn)數(shù)據(jù),從而導(dǎo)致了數(shù)據(jù)傾斜。

  3.3.2 實(shí)現(xiàn)思路

  如果我們判斷那少數(shù)幾個(gè)數(shù)據(jù)量特別多的 key,對(duì)作業(yè)的執(zhí)行和計(jì)算結(jié)果不是特別重要的話,那么干脆 就直接過(guò)濾掉那少數(shù)幾個(gè) key。比如,在 Spark SQL 中可以使用 where 子句過(guò)濾掉這些 key 或者在 SparkCore 中對(duì) RDD 執(zhí)行 filter 算子過(guò)濾掉這些 key。如果需要每次作業(yè)執(zhí)行時(shí),動(dòng)態(tài)判定哪些 key 的數(shù)據(jù)量最多

  然后再進(jìn)行過(guò)濾,那么可以使用 sample 算子對(duì) RDD 進(jìn)行采樣,然后計(jì)算出每個(gè) key 的 數(shù)量,取數(shù)據(jù)量最多的 key 過(guò)濾掉即可。

  3.2.3 實(shí)現(xiàn)原理

  將導(dǎo)致數(shù)據(jù)傾斜的 key 給過(guò)濾掉之后,這些 key 就不會(huì)參與計(jì)算了,自然不可能產(chǎn)生數(shù)據(jù)傾斜。

  3.3.4 方案優(yōu)缺點(diǎn)

  * 優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單,而且效果也很好,可以完全規(guī)避掉數(shù)據(jù)傾斜。

  * 缺點(diǎn):適用場(chǎng)景不多,大多數(shù)情況下,導(dǎo)致傾斜的key還是很多的,并不是只有少數(shù)幾個(gè)

  3.3.5 企業(yè)最佳實(shí)踐

  * 在項(xiàng)目中我們也采用過(guò)這種方案解決數(shù)據(jù)傾斜。有一次發(fā)現(xiàn)某一天 Spark 作業(yè)在運(yùn)行的時(shí)候突然 OOM 了,追查之后發(fā)現(xiàn),是 Hive 表中的某一個(gè) key 在那天數(shù)據(jù)異常,導(dǎo)致數(shù)據(jù)量暴增。因此就采取每次執(zhí) 行前先進(jìn)行采樣,計(jì)算出樣本中數(shù)據(jù)量最大的幾個(gè) key 之后,直接在程序中將那些key給過(guò)濾掉。

  3.4 將reduce join轉(zhuǎn)為map join

  3.4.1 適用場(chǎng)景

  在對(duì) RDD 使用 join 類操作,或者是在 Spark SQL 中使用 join 語(yǔ)句時(shí),而且 join 操作中的一個(gè) RDD 或 表的數(shù)據(jù)量比較小(比如幾百M(fèi)或者一兩G),比較適用此方案。

  在分布式計(jì)算引擎中,實(shí)現(xiàn)Join的思路有兩種: 1、MapJoin,顧名思義,Join邏輯的完成是在 Mapper 階段就完成了,這是假定執(zhí)行的是 MapReduce任務(wù),如果是 Spark任務(wù),表示只用一個(gè) Stage 就執(zhí)行完了 Join 操作。

  * 優(yōu)點(diǎn):避免了兩階段之間的shuffle,效率高,沒(méi)有shuffle也就沒(méi)有了傾斜。

  * 缺點(diǎn):多使用內(nèi)存資源,只適合大小表做join的場(chǎng)景

  2、ReduceJoin,顧名思義,Join邏輯的完成是在 Reducer 階段完成的。那么如果是MapReduce任 務(wù),則表示 Maper階段執(zhí)行完之后把數(shù)據(jù) Shuffle到 Reducer階段來(lái)執(zhí)行 Join 邏輯,那么就可能導(dǎo)致數(shù) 據(jù)傾斜。如果是 Spark任務(wù),意味著,上一個(gè)stage的執(zhí)行結(jié)果數(shù)據(jù)shuffle到 下一個(gè)stage中來(lái)完成 Join 操作,同樣也可能產(chǎn)生數(shù)據(jù)傾斜。

  * 優(yōu)點(diǎn):這是一種通用的join,在不產(chǎn)生數(shù)據(jù)傾斜的情況下,能完成各種類型的join

  * 缺點(diǎn):會(huì)發(fā)生數(shù)據(jù)傾斜的情況

  3.4.2 實(shí)現(xiàn)思路

  不使用join算子進(jìn)行連接操作,而使用Broadcast變量與map類算子實(shí)現(xiàn)join操作,進(jìn)而完全規(guī)避掉 shuffle類的操作,徹底避免數(shù)據(jù)傾斜的發(fā)生和出現(xiàn)。將較小

  RDD中的數(shù)據(jù)直接通過(guò)collect算子拉取到 Driver端的內(nèi)存中來(lái),然后對(duì)其創(chuàng)建一個(gè)Broadcast變量;接著對(duì)另外一個(gè)RDD執(zhí)行map類算子,在算 子函數(shù)內(nèi),從Broadcast變量中獲取較小RDD的全量數(shù)據(jù),與當(dāng)前RDD的每一條數(shù)據(jù)按照連接key進(jìn)行 比對(duì),如果連接key相同的話,那么就將兩個(gè)RDD的數(shù)據(jù)用你需要的方式連接起來(lái)。

  3.4.3 實(shí)現(xiàn)原理

  普通的 join 是會(huì)走 shuffle 過(guò)程的,而一旦 shuffle,就相當(dāng)于會(huì)將相同 key 的數(shù)據(jù)拉取到一個(gè) shuffle read task 中再進(jìn)行 join,此時(shí)就是 reduce join。但是如果一個(gè) RDD 是比較小的,則可以采用廣播小 RDD 全量數(shù)據(jù) +map 算子來(lái)實(shí)現(xiàn)與 join 同樣的效果,也就是 map join,此時(shí)就不會(huì)發(fā)生 shuffle 操 作,也就不會(huì)發(fā)生數(shù)據(jù)傾斜。具體原理如下圖所示。

  3.4.4 方案優(yōu)缺點(diǎn)

  * 優(yōu)點(diǎn): 對(duì)join操作導(dǎo)致的數(shù)據(jù)傾斜,效果非常好,因?yàn)楦揪筒粫?huì)發(fā)生shuffle,也就根本不會(huì)發(fā)生數(shù)據(jù)傾斜。

  * 缺點(diǎn): 適用場(chǎng)景較少,因?yàn)檫@個(gè)方案只適用于一個(gè)大表和一個(gè)小表的情況。畢竟我們需要將小表進(jìn)行廣播,此時(shí)會(huì)比 較消耗內(nèi)存資源,driver 和每個(gè)Executor 內(nèi)存中都會(huì)駐留一份小 RDD 的全量數(shù)據(jù)。如果我們廣播出去 的 RDD 數(shù)據(jù)比較大,比如 10G 以上,那么就可能發(fā)生內(nèi)存溢出了。因此并不適合兩個(gè)都是大表的情況。

  3.5 采樣傾斜 key并分拆 join操作

  3.5.1 適用場(chǎng)景

  兩個(gè) RDD/Hive 表進(jìn)行 join 的時(shí)候,如果數(shù)據(jù)量都比較大,無(wú)法采用3.5方案,那么此時(shí)可以看一 下兩個(gè) RDD/Hive 表中的 key 分布情況。如果出現(xiàn)數(shù)據(jù)傾斜,是因?yàn)槠渲心骋粋€(gè) RDD/Hive 表中的少數(shù) 幾個(gè) key 的數(shù)據(jù)量過(guò)大,而另一個(gè) RDD/Hive 表中的所有 key 都分布比較均勻,那么采用這個(gè)解決方案 是比較合適的。

  3.5.2 實(shí)現(xiàn)思路

  1. 對(duì)包含少數(shù)幾個(gè)數(shù)據(jù)量過(guò)大的key的那個(gè)RDD,通過(guò)sample算子采樣出一份樣本來(lái),然后統(tǒng)計(jì)一下每個(gè) key的數(shù)量,計(jì)算出來(lái)數(shù)據(jù)量最大的是哪幾個(gè)key。

  2. 然后將這幾個(gè)key對(duì)應(yīng)的數(shù)據(jù)從原來(lái)的RDD中拆分出來(lái),形成一個(gè)單獨(dú)的RDD,并給每個(gè)key都打上n以內(nèi)的 隨機(jī)數(shù)作為前綴,而不會(huì)導(dǎo)致傾斜的大部分key形成另外一個(gè)RDD。

  3. 接著將需要join的另一個(gè)RDD,也過(guò)濾出來(lái)那幾個(gè)傾斜key對(duì)應(yīng)的數(shù)據(jù)并形成一個(gè)單獨(dú)的RDD,將每條數(shù)據(jù) 膨脹成n條數(shù)據(jù),這n條數(shù)據(jù)都按順序附加一個(gè)0~n的前綴,不會(huì)導(dǎo)致傾斜的大部分key也形成另外一個(gè)RDD。

  4. 再將附加了隨機(jī)前綴的獨(dú)立RDD與另一個(gè)膨脹n倍的獨(dú)立RDD進(jìn)行join,此時(shí)就可以將原先相同的key打散 成n份,分散到多個(gè)task中去進(jìn)行join了。

  5. 而另外兩個(gè)普通的RDD就照常join即可。

  6. 最后將兩次join的結(jié)果使用union算子合并起來(lái)即可,就是最終的join結(jié)果。

  3.5.3 實(shí)現(xiàn)原理

  對(duì)于 join 導(dǎo)致的數(shù)據(jù)傾斜,如果只是某幾個(gè) key 導(dǎo)致了傾斜,可以將少數(shù)幾個(gè) key 分拆成獨(dú)立 RDD, 并附加隨機(jī)前綴打散成 n 份去進(jìn)行join,此時(shí)這幾個(gè) key 對(duì)應(yīng)的數(shù)據(jù)就不會(huì)集中在少數(shù)幾個(gè) task 上, 而是分散到多個(gè) task 進(jìn)行 join 了。具體原理見(jiàn)下圖。

  3.5.4 方案優(yōu)缺點(diǎn)

  * 優(yōu)點(diǎn): 對(duì)于join導(dǎo)致的數(shù)據(jù)傾斜,如果只是某幾個(gè)key導(dǎo)致了傾斜,采用該方式可以用最有效的方式打散key進(jìn)行 join。而且只需要針對(duì)少數(shù)傾斜key對(duì)應(yīng)的數(shù)據(jù)進(jìn)行擴(kuò)容n倍,不需要對(duì)全量數(shù)據(jù)進(jìn)行擴(kuò)容。避免了占用過(guò)多 內(nèi)存。

  * 缺點(diǎn): 如果導(dǎo)致傾斜的key特別多的話,比如成千上萬(wàn)個(gè)key都導(dǎo)致數(shù)據(jù)傾斜,那么這種方式也不適合。

  3.6 兩階段聚合(局部聚合+全局聚合)

  3.6.1 適用場(chǎng)景

  對(duì)RDD執(zhí)行reduceByKey等聚合類shuffle算子或者在Spark SQL中使用group by語(yǔ)句進(jìn)行分組聚合時(shí), 比較適用這種方案。

  3.6.2 實(shí)現(xiàn)思路

  這個(gè)方案的核心實(shí)現(xiàn)思路就是進(jìn)行兩階段聚合。第一次是局部聚合,先給每個(gè)key都打上一個(gè)隨機(jī)數(shù), 比如10以內(nèi)的隨機(jī)數(shù),此時(shí)原先一樣的key就變成不一樣的了,比如(hello, 1) (hello, 1) (hello, 1) (hello, 1),就會(huì)變成(1hello, 1) (1hello, 1) (2hello, 1) (2hello, 1)。接著對(duì)打上隨機(jī)數(shù)后的數(shù)據(jù),執(zhí)行 reduceByKey等聚合操作,進(jìn)行局部聚合,那么局部聚合結(jié)果,就會(huì)變成了(1hello, 2) (2hello, 2)。然 后將各個(gè)key的前綴給去掉,就會(huì)變成(hello,2)(hello,2),再次進(jìn)行全局聚合操作,就可以得到最終結(jié)果 了,比如(hello, 4)。

  3.6.3 實(shí)現(xiàn)原理

  將原本相同的key通過(guò)附加隨機(jī)前綴的方式,變成多個(gè)不同的key,就可以讓原本被一個(gè)task處理的數(shù)據(jù) 分散到多個(gè)task上去做局部聚合,進(jìn)而解決單個(gè)task處理數(shù)據(jù)量過(guò)多的問(wèn)題。接著去除掉隨機(jī)前綴,再 次進(jìn)行全局聚合,就可以得到最終的結(jié)果。具體原理見(jiàn)下圖。

Spark 數(shù)據(jù)傾斜調(diào)優(yōu)10策02

 

  3.6.4 方案優(yōu)缺點(diǎn)

  * 優(yōu)點(diǎn): 對(duì)于聚合類的shuffle操作導(dǎo)致的數(shù)據(jù)傾斜,效果是非常不錯(cuò)的。通常都可以解決掉數(shù)據(jù)傾斜,或者至少是大 幅度緩解數(shù)據(jù)傾斜,將Spark作業(yè)的性能提升數(shù)倍以上。

  * 缺點(diǎn): 僅僅適用于聚合類的shuffle操作,適用范圍相對(duì)較窄。如果是join類的shuffle操作,還得用其他的解決 方案。

  3.7 使用隨機(jī)前綴和擴(kuò)容 RDD 進(jìn)行 join

  3.7.1 適用場(chǎng)景

  如果在進(jìn)行 join 操作時(shí),RDD 中有大量的 key 導(dǎo)致數(shù)據(jù)傾斜,那么進(jìn)行分拆 key 也沒(méi)什么意義。

  3.7.2 實(shí)現(xiàn)思路

  1. 該方案的實(shí)現(xiàn)思路基本和3.5方案類似,首先查看 RDD/Hive 表中的數(shù)據(jù)分布情況,找到那個(gè)造成 數(shù)據(jù)傾斜的 RDD/Hive 表,比如有多個(gè)key 都對(duì)應(yīng)了超過(guò)1萬(wàn)條數(shù)據(jù)。

  2. 然后將該RDD的每條數(shù)據(jù)都打上一個(gè)n以內(nèi)的隨機(jī)前綴。

  3. 同時(shí)對(duì)另外一個(gè)正常的RDD進(jìn)行擴(kuò)容,將每條數(shù)據(jù)都擴(kuò)容成n條數(shù)據(jù),擴(kuò)容出來(lái)的每條數(shù)據(jù)都依次打上一個(gè) 0~n的前綴。

  4. 最后將兩個(gè)處理后的RDD進(jìn)行join即可。

  3.7.3 實(shí)現(xiàn)原理

  將原先一樣的 key 通過(guò)附加隨機(jī)前綴變成不一樣的key,然后就可以將這些處理后的“不同key”分散到多 個(gè)task中去處理,而不是讓一個(gè)task處理大量的相同key。該方案與3.6方案的不同之處就在于,上 一種方案是盡量只對(duì)少數(shù)傾斜key對(duì)應(yīng)的數(shù)據(jù)進(jìn)行特殊處理,由于處理過(guò)程需要擴(kuò)容RDD,因此上一種 方案擴(kuò)容RDD后對(duì)內(nèi)存的占用并不大;而這一種方案是針對(duì)有大量?jī)A斜key的情況,沒(méi)法將部分key拆分 出來(lái)進(jìn)行單獨(dú)處理,因此只能對(duì)整個(gè)RDD進(jìn)行數(shù)據(jù)擴(kuò)容,對(duì)內(nèi)存資源要求很高。

Spark 數(shù)據(jù)傾斜調(diào)優(yōu)10策03

 

  3.7.4 方案優(yōu)缺點(diǎn)

  * 優(yōu)點(diǎn): 對(duì)join類型的數(shù)據(jù)傾斜基本都可以處理,而且效果也相對(duì)比較顯著,性能提升效果非常不錯(cuò)。

  * 缺點(diǎn): 該方案更多的是緩解數(shù)據(jù)傾斜,而不是徹底避免數(shù)據(jù)傾斜。而且需要對(duì)整個(gè)RDD進(jìn)行擴(kuò)容,對(duì)內(nèi)存資源要求很 高。

  3.7.5 企業(yè)最佳實(shí)踐

  * 開(kāi)發(fā)一個(gè)數(shù)據(jù)需求的時(shí)候,發(fā)現(xiàn)一個(gè)join導(dǎo)致了數(shù)據(jù)傾斜。優(yōu)化之前,作業(yè)的執(zhí)行時(shí)間大約是60分鐘左右;使用該方案優(yōu)化之后,執(zhí)行時(shí)間縮短到10分鐘左右,性能提升了6倍。

  3.8 任務(wù)橫切,一分為二,單獨(dú)處理

  3.8.1 適用場(chǎng)景

  有時(shí)候,一個(gè)Spark應(yīng)用程序中,導(dǎo)致傾斜的因素不是一個(gè)單一的,比如有一部分傾斜的因素是null, 有一部分傾斜的因素是某些個(gè)key分布特別多。那么拆分出來(lái)也得使用不同的手段來(lái)處理

  3.8.2 實(shí)現(xiàn)思路

  在了解清楚數(shù)據(jù)的分布規(guī)律,以及確定了數(shù)據(jù)傾斜是由何種原因?qū)е碌?,那么按照這些原因,進(jìn)行數(shù)據(jù)的拆分,然后單獨(dú)處理每個(gè)部分的數(shù)據(jù),最后把結(jié)果合起來(lái)。

  3.8.3 實(shí)現(xiàn)原理

  3.6方案其實(shí)是一種縱切,3.8方案就是一種橫切。原理同思路。

  3.8.4 方案優(yōu)缺點(diǎn)

  * 優(yōu)點(diǎn): 將多種簡(jiǎn)單的方案綜合起來(lái),解決一個(gè)復(fù)雜的問(wèn)題??梢运闵弦环N萬(wàn)能的方案。

  * 缺點(diǎn): 確定數(shù)據(jù)傾斜的因素比較復(fù)雜,導(dǎo)致解決該數(shù)據(jù)傾斜的方案比較難實(shí)現(xiàn)落地。代碼復(fù)雜度也較高。

  3.9 多方案組合使用

  * 在實(shí)踐中發(fā)現(xiàn),很多情況下,如果只是處理較為簡(jiǎn)單的數(shù)據(jù)傾斜場(chǎng)景,那么使用上述方案中的某一種基 本就可以解決。但是如果要處理一個(gè)較為復(fù)雜的數(shù)據(jù)傾斜場(chǎng)景,那么可能需要將多種方案組合起來(lái)使 用。比如說(shuō),我們針對(duì)出現(xiàn)了多個(gè)數(shù)據(jù)傾斜環(huán)節(jié)的Spark作業(yè),可以先運(yùn)用3.1和3.2方案,預(yù)處理一 部分?jǐn)?shù)據(jù),并過(guò)濾一部分?jǐn)?shù)據(jù)來(lái)緩解;其次可以對(duì)某些shuffle操作提升并行度,優(yōu)化其性能;最后還可 以針對(duì)不同的聚合或join操作,選擇一種方案來(lái)優(yōu)化其性能。大家需要對(duì)這些方案的思路和原理都透徹 理解之后,在實(shí)踐中根據(jù)各種不同的情況,靈活運(yùn)用多種方案,來(lái)解決自己的數(shù)據(jù)傾斜問(wèn)題。

  * 如果這多種方案,組合使用也不行,最后一招:自定義分區(qū)規(guī)則

  3.10 自定義Partitioner

  3.10.1 適用場(chǎng)景

  大量不同的Key被分配到了相同的Task造成該Task數(shù)據(jù)量過(guò)大。

  3.10.2 實(shí)現(xiàn)思路

  先通過(guò)抽樣,了解數(shù)據(jù)的 key 的分布規(guī)律,然后根據(jù)規(guī)律,去定制自己的數(shù)據(jù)分區(qū)規(guī)則,盡量保證所有 的 Task 的數(shù)據(jù)量相差無(wú)幾。

  3.10.3 實(shí)現(xiàn)原理

  使用自定義的 Partitioner(默認(rèn)為HashPartitioner),將原本被分配到同一個(gè) Task 的不同 Key 分配 到不同 Task。

  3.10.4 分區(qū)方案

  • 隨機(jī)分區(qū)

  * 優(yōu)點(diǎn): 數(shù)據(jù)分布均勻

  * 缺點(diǎn): 具有相同特點(diǎn)的數(shù)據(jù)不會(huì)保證被分配到相同的分區(qū)

  • 輪詢分區(qū)

  * 優(yōu)點(diǎn): 確保一定不會(huì)出現(xiàn)數(shù)據(jù)傾斜

  * 缺點(diǎn): 無(wú)法根據(jù)存儲(chǔ)/計(jì)算能力分配存儲(chǔ)/計(jì)算壓力

  • Hash散列

  * 優(yōu)點(diǎn): 具有相同特點(diǎn)的數(shù)據(jù)保證被分配到相同的分區(qū)

  * 缺點(diǎn): 極容易產(chǎn)生數(shù)據(jù)傾斜

  • 范圍分區(qū)

  * 優(yōu)點(diǎn): 相鄰的數(shù)據(jù)都在相同的分區(qū)

  * 缺點(diǎn): 部分分區(qū)的數(shù)據(jù)量會(huì)超出其他的分區(qū),需要進(jìn)行裂變以保持所有分區(qū)的數(shù)據(jù)量是均勻的,如果每個(gè)分區(qū)不排序,那么裂變就會(huì)非常困難

  3.10.5 方案優(yōu)缺點(diǎn)

  * 優(yōu)點(diǎn): 靈活,通用。

  * 缺點(diǎn): 必須根據(jù)對(duì)應(yīng)的場(chǎng)景設(shè)計(jì)合理的分區(qū)方案。沒(méi)有現(xiàn)成的方案可用,需臨時(shí)實(shí)現(xiàn)。

  四、案例

  4.1 問(wèn)題

  如果是兩張?zhí)卮髮挶碜?Join 怎么辦?

  # 解決方案: 位圖法

  4.2 例子

  最近7天連續(xù)登錄的用戶有哪些?假如每天登陸的用戶存在多張表或者一張表的多個(gè)分區(qū)中。如果用戶基數(shù)很高比如10億。 那Join的方案將會(huì)比較低效。位圖解決是一個(gè)不錯(cuò)的方案

  4.3 實(shí)現(xiàn)思路

  對(duì)每一天的用戶登陸數(shù)據(jù)維護(hù)一個(gè)Bitmap, 如果用戶登錄對(duì)應(yīng)的Bitmap位就置為1。將7個(gè)Bitmap按位求與,就可以得到7天連續(xù)登錄的用戶了。

Spark 數(shù)據(jù)傾斜調(diào)優(yōu)10策04

tags:
聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
請(qǐng)您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
免費(fèi)領(lǐng)取
今日已有369人領(lǐng)取成功
劉同學(xué) 138****2860 剛剛成功領(lǐng)取
王同學(xué) 131****2015 剛剛成功領(lǐng)取
張同學(xué) 133****4652 剛剛成功領(lǐng)取
李同學(xué) 135****8607 剛剛成功領(lǐng)取
楊同學(xué) 132****5667 剛剛成功領(lǐng)取
岳同學(xué) 134****6652 剛剛成功領(lǐng)取
梁同學(xué) 157****2950 剛剛成功領(lǐng)取
劉同學(xué) 189****1015 剛剛成功領(lǐng)取
張同學(xué) 155****4678 剛剛成功領(lǐng)取
鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
董同學(xué) 138****2867 剛剛成功領(lǐng)取
周同學(xué) 136****3602 剛剛成功領(lǐng)取
相關(guān)推薦HOT
什么是PlatformIo?

PlatformIO是什么PlatformIO是一個(gè)全面的物聯(lián)網(wǎng)開(kāi)發(fā)平臺(tái),它為眾多硬件平臺(tái)和開(kāi)發(fā)環(huán)境提供了統(tǒng)一的工作流程,有效簡(jiǎn)化了開(kāi)發(fā)過(guò)程,并能兼容各種...詳情>>

2023-10-14 12:55:06
云快照與自動(dòng)備份有什么區(qū)別?

1、定義和目標(biāo)不同云快照的主要目標(biāo)是提供一種快速恢復(fù)數(shù)據(jù)的方法,它只記錄在快照時(shí)間點(diǎn)后的數(shù)據(jù)變化,而不是所有的數(shù)據(jù)。自動(dòng)備份的主要目標(biāo)...詳情>>

2023-10-14 12:48:59
服務(wù)器為什么要用Linux?

服務(wù)器為什么要用Linux作為服務(wù)器操作系統(tǒng)的優(yōu)選,Linux在眾多選擇中脫穎而出。Linux作為服務(wù)器操作系統(tǒng)的優(yōu)選,有其獨(dú)特的優(yōu)勢(shì)和特點(diǎn)。包括其...詳情>>

2023-10-14 12:34:11
ORM解決的主要問(wèn)題是什么?

ORM(對(duì)象關(guān)系映射)解決的主要問(wèn)題是將關(guān)系數(shù)據(jù)庫(kù)與面向?qū)ο缶幊讨g的映射困境。在傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)中,數(shù)據(jù)以表格的形式存儲(chǔ),而在面向?qū)ο?..詳情>>

2023-10-14 12:26:19
Go為什么不支持三元運(yùn)算符?

Go為什么不支持三元運(yùn)算符Go語(yǔ)言是一種以簡(jiǎn)潔和有效性為目標(biāo)的編程語(yǔ)言,因此在設(shè)計(jì)過(guò)程中,Go的設(shè)計(jì)者刻意排除了一些他們認(rèn)為可能導(dǎo)致復(fù)雜性或...詳情>>

2023-10-14 12:12:36