一、背景
這個(gè)方案的實(shí)現(xiàn)思路,跟大家解析一下:其實(shí)關(guān)鍵之處在于邑彪,將發(fā)生數(shù)據(jù)傾斜的key,單獨(dú)拉出來(lái)惯裕,放到一個(gè)RDD中去;就用這個(gè)原本會(huì)傾斜的key RDD跟其他RDD绣硝,單獨(dú)去join一下蜻势,這個(gè)時(shí)候,key對(duì)應(yīng)的數(shù)據(jù)鹉胖,可能就會(huì)分散到多個(gè)task中去進(jìn)行join操作握玛。
就不至于說(shuō)是,這個(gè)key跟之前其他的key混合在一個(gè)RDD中時(shí)甫菠,肯定是會(huì)導(dǎo)致一個(gè)key對(duì)應(yīng)的所有數(shù)據(jù)挠铲,都到一個(gè)task中去,就會(huì)導(dǎo)致數(shù)據(jù)傾斜淑蔚。
二市殷、流程圖解
這種方案什么時(shí)候適合使用?
1刹衫、優(yōu)先對(duì)于join醋寝,肯定是希望能夠采用上一講講的,reduce join轉(zhuǎn)換map join带迟。兩個(gè)RDD數(shù)據(jù)都比較大音羞,那么就不要那么搞了。
2仓犬、針對(duì)你的RDD的數(shù)據(jù)嗅绰,你可以自己把它轉(zhuǎn)換成一個(gè)中間表搀继,或者是直接用countByKey()的方式,你可以看一下這個(gè)RDD各個(gè)key對(duì)應(yīng)的數(shù)據(jù)量财边;此時(shí)如果你發(fā)現(xiàn)整個(gè)RDD就一個(gè),或者少數(shù)幾個(gè)key点骑,是對(duì)應(yīng)的數(shù)據(jù)量特別多;盡量建議憨募,比如就是一個(gè)key對(duì)應(yīng)的數(shù)據(jù)量特別多。
3袁辈、此時(shí)可以采用咱們的這種方案菜谣,單拉出來(lái)那個(gè)最多的key;單獨(dú)進(jìn)行join甘磨,盡可能地將key分散到各個(gè)task上去進(jìn)行join操作眯停。
什么時(shí)候不適用呢莺债?
4签夭、如果一個(gè)RDD中,導(dǎo)致數(shù)據(jù)傾斜的key措拇,特別多慎宾;那么此時(shí),最好還是不要這樣了券犁;還是使用我們最后一個(gè)方案汹碱,終極的join數(shù)據(jù)傾斜的解決方案咳促。
三、進(jìn)一步優(yōu)化
就是說(shuō)褂删,咱們單拉出來(lái)了尺迂,一個(gè)或者少數(shù)幾個(gè)可能會(huì)產(chǎn)生數(shù)據(jù)傾斜的key,然后還可以進(jìn)行更加優(yōu)化的一個(gè)操作蹲盘;
對(duì)于那個(gè)key膳音,從另外一個(gè)要join的表中,也過(guò)濾出來(lái)一份數(shù)據(jù)苍凛,比如可能就只有一條數(shù)據(jù)醇蝴。userid2infoRDD,一個(gè)userid key悠栓,就對(duì)應(yīng)一條數(shù)據(jù)惭适。
然后呢,采取對(duì)那個(gè)只有一條數(shù)據(jù)的RDD往枷,進(jìn)行flatMap操作凄杯,打上100個(gè)隨機(jī)數(shù),作為前綴墓臭,返回100條數(shù)據(jù)窿锉。
單獨(dú)拉出來(lái)的可能產(chǎn)生數(shù)據(jù)傾斜的RDD膝舅,給每一條數(shù)據(jù),都打上一個(gè)100以?xún)?nèi)的隨機(jī)數(shù)洼滚,作為前綴技潘。
再去進(jìn)行join享幽,是不是性能就更好了“诿梗肯定可以將數(shù)據(jù)進(jìn)行打散,去進(jìn)行join搭盾。join完以后婉支,可以執(zhí)行map操作向挖,去將之前打上的隨機(jī)數(shù),給去掉,然后再和另外一個(gè)普通RDD join以后的結(jié)果幕侠,進(jìn)行union操作晤硕。