日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何解决数据倾斜问题?

發(fā)布時間:2023/12/20 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何解决数据倾斜问题? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載:https://blog.csdn.net/Mr_HHH/article/details/89399518

今天在工作中遇到了數(shù)據(jù)傾斜的問題,一條SQL執(zhí)行了8小時才執(zhí)行完,看計劃是先join再做distinct,卡在了join上,數(shù)據(jù)量比較大,并且重復(fù)數(shù)據(jù)比較多,后續(xù)經(jīng)過分析計劃,查資料,在不影響結(jié)果的前提下,改為先進(jìn)行distinct,然后再join,最后在2min12s就出了結(jié)果。

在網(wǎng)上查找資料時,發(fā)現(xiàn)與這篇文章中的解決數(shù)據(jù)傾斜的辦法有相同的部分。

目前流行的大數(shù)據(jù)相關(guān)的計算框架之所以能夠處理大量的數(shù)據(jù)和計算,基本上都是依賴分布式計算的思想,即由一個通過某種組織關(guān)系連接在一起的集群來共同完成計算任務(wù)。

這是一個非常好的計算模型,無論多大的數(shù)據(jù)量,只要集群可以擴(kuò)展,就能夠擴(kuò)充算力,自如應(yīng)對,但與此同時,也為數(shù)據(jù)傾斜的產(chǎn)生埋下了伏筆。

1:什么是數(shù)據(jù)傾斜?

前面提到分布式計算,是一個集群共同承擔(dān)計算任務(wù),理想狀態(tài)下,每個計算節(jié)點應(yīng)該承擔(dān)相近數(shù)據(jù)量的計算任務(wù),然而實際情況通常不會這么理想,數(shù)據(jù)分配嚴(yán)重不均就會產(chǎn)生數(shù)據(jù)傾斜。我們先來給數(shù)據(jù)傾斜下個明確點的定義。

數(shù)據(jù)傾斜,指的是并行處理的過程中,某些分區(qū)或節(jié)點處理的數(shù)據(jù),顯著高于其他分區(qū)或節(jié)點,導(dǎo)致這部分的數(shù)據(jù)處理任務(wù)比其他任務(wù)要大很多,從而成為這個階段執(zhí)行最慢的部分,進(jìn)而成為整個作業(yè)執(zhí)行的瓶頸,甚至直接導(dǎo)致作業(yè)失敗。

舉個實際發(fā)生的例子說明下,一個spark作業(yè),其中有個stage是由200個partition組成,在實際執(zhí)行中,有198個partition在10秒內(nèi)就完成了,但是有兩個partition執(zhí)行了3分鐘都沒有完成,并且在執(zhí)行5分鐘后失敗了。這便是典型的數(shù)據(jù)傾斜場景,通過觀察SparkUI發(fā)現(xiàn)這兩個partition要處理的數(shù)據(jù)是其他partition的30多倍,屬于比較嚴(yán)重的數(shù)據(jù)傾斜。

2:數(shù)據(jù)傾斜的危害

知道了什么是數(shù)據(jù)傾斜,那么它到底有什么危害,讓大家這么痛恨它的同時,又很畏懼它呢。

數(shù)據(jù)傾斜主要有三點危害:

危害一:任務(wù)長時間掛起,資源利用率下降

計算作業(yè)通常是分階段進(jìn)行的,階段與階段之間通常存在數(shù)據(jù)上的依賴關(guān)系,也就是說后一階段需要等前一階段執(zhí)行完才能開始。

舉個例子,Stage1在Stage0之后執(zhí)行,假如Stage1依賴Stage0產(chǎn)生的數(shù)據(jù)結(jié)果,那么Stage1必須等待Stage0執(zhí)行完成后才能開始,如果這時Stage0因為數(shù)據(jù)傾斜問題,導(dǎo)致任務(wù)執(zhí)行時長過長,或者直接掛起,那么Stage1將一直處于等待狀態(tài),整個作業(yè)也就一直掛起。這個時候,資源被這個作業(yè)占據(jù),但是卻只有極少數(shù)task在執(zhí)行,造成計算資源的嚴(yán)重浪費,利用率下降。

危害二:由引發(fā)內(nèi)存溢出,導(dǎo)致任務(wù)失敗

數(shù)據(jù)發(fā)生傾斜時,可能導(dǎo)致大量數(shù)據(jù)集中在少數(shù)幾個節(jié)點上,在計算執(zhí)行中由于要處理的數(shù)據(jù)超出了單個節(jié)點的能力范圍,最終導(dǎo)致內(nèi)存被撐爆,報OOM異常,直接導(dǎo)致任務(wù)失敗。

危害三:作業(yè)執(zhí)行時間超出預(yù)期,導(dǎo)致后續(xù)依賴數(shù)據(jù)結(jié)果的作業(yè)出錯

有時候作業(yè)與作業(yè)之間,并沒有構(gòu)建強(qiáng)依賴關(guān)系,而是通過執(zhí)行時間的前后時間差來調(diào)度,當(dāng)前置作業(yè)未在預(yù)期時間范圍內(nèi)完成執(zhí)行,那么當(dāng)后續(xù)作業(yè)啟動時便無法讀取到其所需要的最新數(shù)據(jù),從而導(dǎo)致連續(xù)出錯。

可以看出,數(shù)據(jù)傾斜問題,就像是一個隱藏的殺手,潛伏在數(shù)據(jù)處理與分析的過程中,只要一出手,非死即傷。那么它又是如何產(chǎn)生的呢?想要解決它,我們就要先了解它。

3:為什么會產(chǎn)生數(shù)據(jù)傾斜?

3.1:讀入數(shù)據(jù)的時候就是傾斜的

讀入數(shù)據(jù)是計算任務(wù)的開始,但是往往這個階段就可能已經(jīng)開始出現(xiàn)問題了。

對于一些本身就可能傾斜的數(shù)據(jù)源,在讀入階段就可能出現(xiàn)個別partition執(zhí)行時長過長或直接失敗,如讀取id分布跨度較大的mysql數(shù)據(jù)、partition分配不均的kafka數(shù)據(jù)或不可分割的壓縮文件。

這些場景下,數(shù)據(jù)在讀取階段或者讀取后的第一個計算階段,就會容易執(zhí)行過慢或報錯。

3.2:shuffle產(chǎn)生傾斜

在shuffle階段造成傾斜,在實際的工作中更加常見,比如特定key值數(shù)量過多,導(dǎo)致join發(fā)生時,大量數(shù)據(jù)涌向一個節(jié)點,導(dǎo)致數(shù)據(jù)嚴(yán)重傾斜,個別節(jié)點的讀寫壓力是其他節(jié)點的好幾倍,容易引發(fā)OOM錯誤。

3.3:過濾導(dǎo)致傾斜

有些場景下,數(shù)據(jù)原本是均衡的,但是由于進(jìn)行了一系列的數(shù)據(jù)剔除操作,可能在過濾掉大量數(shù)據(jù)后,造成數(shù)據(jù)的傾斜。

例如,大部分節(jié)點都被過濾掉了很多數(shù)據(jù),只剩下少量數(shù)據(jù),但是個別節(jié)點的數(shù)據(jù)被過濾掉的很少,保留著大部分的數(shù)據(jù)。這種情況下,一般不會OOM,但是傾斜的數(shù)據(jù)可能會隨著計算逐漸累積,最終引發(fā)問題。

4:怎么預(yù)防或解決數(shù)據(jù)傾斜問題?

4.1.盡量保證數(shù)據(jù)源是均衡的

程序讀入的數(shù)據(jù)源通常是上個階段其他作業(yè)產(chǎn)生的,那么我們在上個階段作業(yè)生成數(shù)據(jù)時,就要注意這個問題,盡量不要給下游作業(yè)埋坑。

如果所有作業(yè)都注意到并謹(jǐn)慎處理了這個問題,那么出現(xiàn)讀入時傾斜的可能性會大大降低。

這個有個小建議,在程序輸出寫文件時,盡量不要用coalesce,而是用repartition,這樣寫出的數(shù)據(jù),各文件大小往往是均衡的。

4.2.對大數(shù)據(jù)集做過濾,結(jié)束后做repartition

對比較大的數(shù)據(jù)集做完過濾后,如果過濾掉了絕大部分?jǐn)?shù)據(jù),在進(jìn)行下一步操作前,最好可以做一次repartition,讓數(shù)據(jù)重回均勻分布的狀態(tài),否則失衡的數(shù)據(jù)集,在進(jìn)行后續(xù)計算時,可能會逐漸累積傾斜的狀態(tài),容易產(chǎn)生錯誤。

4.3.對小表進(jìn)行廣播

如果兩個數(shù)據(jù)量差異較大的表做join時,發(fā)生數(shù)據(jù)傾斜的常見解決方法,是將小表廣播到每個節(jié)點去,這樣就可以實現(xiàn)map端join,從而省掉shuffle,避免了大量數(shù)據(jù)在個別節(jié)點上的匯聚,執(zhí)行效率也大大提升。

4.4.編碼時要注意,不要人為造成傾斜

在寫代碼時,也要多加注意不要使用容易出問題的算子,如上文提到的coalesce。

另外,也要注意不要人為造成傾斜,如作者一次在幫別人排查傾斜問題時發(fā)現(xiàn),他在代碼中使用開窗函數(shù),其中寫到over (partition by 1),這樣就把所有數(shù)據(jù)分配到一個分區(qū)內(nèi),人為造成了傾斜。

4.5.join前優(yōu)化

個別場景下,兩個表join,某些特殊key值可能很多,很容易產(chǎn)生數(shù)據(jù)傾斜,這時可以根據(jù)實際計算進(jìn)行join前優(yōu)化。

如計算是先join后根據(jù)key聚合,那可以改為先根據(jù)key聚合然后再join。又如,需求是join后做distinct操作,在不影響結(jié)果的前提下,可以改為先distinct,然后再join。這些措施都是可以有效避免重復(fù)key過多導(dǎo)致join時傾斜。

4.6.具體問題具體分析

某些具體問題或者解決方案,不具備普遍性,但是也可以作為一種思路參考。

例如,讀入mysql數(shù)據(jù)時傾斜,這通常是由于mysql的id分布嚴(yán)重不均,中間存在跨度很大的區(qū)間造成的。解決方法有兩種,一是加大讀取時的分區(qū)數(shù),將傾斜的區(qū)間劃分開;另一種是,先把id取出來進(jìn)行等寬切割,確保每個區(qū)段的id數(shù)量一致,之后再對各區(qū)間進(jìn)行數(shù)據(jù)讀取。

本文介紹了什么是數(shù)據(jù)傾斜、它的危害、產(chǎn)生的原因及一些常用的解決方案,希望可以幫助大家,加深對數(shù)據(jù)傾斜的認(rèn)識,如果遇到類似問題,可以快速上手解決掉。

?

總結(jié)

以上是生活随笔為你收集整理的如何解决数据倾斜问题?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。