背景
spark任務(wù)中最常見(jiàn)的耗時(shí)原因就是數(shù)據(jù)分布不均勻,從而導(dǎo)致有些task運(yùn)行時(shí)間很長(zhǎng),長(zhǎng)尾效應(yīng)導(dǎo)致的整個(gè)job運(yùn)行耗時(shí)很長(zhǎng)
數(shù)據(jù)傾斜調(diào)優(yōu)
首先我們要定位數(shù)據(jù)傾斜,我們可以通過(guò)在spark ui界面中查看某個(gè)stage下的task的耗時(shí),如果發(fā)現(xiàn)某些task耗時(shí)很長(zhǎng),對(duì)應(yīng)要處理的數(shù)據(jù)很多,證明有數(shù)據(jù)傾斜的問(wèn)題,那么我們?cè)趺刺幚頂?shù)據(jù)傾斜呢,
1.增加shuffle操作的并行度,也就是設(shè)置spark.sql.shuffle.partitions的值,這個(gè)參數(shù)可以提高shuffle read task的并行度,也就是處理當(dāng)某個(gè)stage下面task數(shù)量很少的問(wèn)題,通過(guò)提供并行度,提高性能–備注:這里順帶說(shuō)下shuffle write task,shuffle write task是shuffle read task的前一個(gè)階段的任務(wù),一般來(lái)說(shuō)其是否均勻是由shuffle read task任務(wù)的數(shù)量決定的
2.對(duì)于兩個(gè)大表的join時(shí),如果某個(gè)大表數(shù)據(jù)不均勻,那么可以對(duì)這個(gè)大表的數(shù)值都增加一個(gè)0-n的隨機(jī)數(shù),另外一個(gè)大表膨脹n倍,每個(gè)數(shù)值M都膨脹為M-0,M-1…M-n,然后在對(duì)兩個(gè)表進(jìn)行join操作,這種情況下雖然其中的一個(gè)大表數(shù)據(jù)膨脹了n倍,但是這點(diǎn)性能消耗是值得的,因?yàn)檫@樣操作后join的操作就會(huì)非常快了
3.對(duì)于group by聚合,可以采用兩階段聚合的方式,先進(jìn)行局部聚合再進(jìn)行全局聚合的方式進(jìn)行,局部聚合方式是先對(duì)表的數(shù)值都增加一個(gè)隨機(jī)數(shù)0-n,然后group by聚合,得到一個(gè)聚合的中間結(jié)果,然后再次對(duì)這個(gè)中間結(jié)果去掉隨機(jī)數(shù)前綴后進(jìn)行g(shù)roup by聚合,得到一個(gè)全局的聚合結(jié)果
4.對(duì)于大表和小表的join時(shí),我們可以對(duì)小表進(jìn)行broadcast操作,把小表進(jìn)行廣播,這樣driver和executor的內(nèi)存中都會(huì)有一份小表的rdd數(shù)據(jù),這樣executor進(jìn)行join操作時(shí)使用來(lái)自小表的基于內(nèi)存的操作就會(huì)非??歙C備注:driver內(nèi)存中也有一份小表的數(shù)據(jù)是因?yàn)閐river要把這份小表的數(shù)據(jù)收集到自己的本地內(nèi)存中,然后再分發(fā)到各個(gè)executor的內(nèi)存中,所以broadcast廣播的情況下,記得要同時(shí)增加driver和executor的內(nèi)存文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-832564.html
參考文獻(xiàn):https://zhuanlan.zhihu.com/p/22024169文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-832564.html
到了這里,關(guān)于spark 的group by ,join數(shù)據(jù)傾斜調(diào)優(yōu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!