當(dāng)?shù)谝淮螌?duì)RDD2執(zhí)行算子鸠儿,獲取RDD3的時(shí)候,就會(huì)從RDD1開(kāi)始計(jì)算厕氨,就是讀取HDFS文件进每,然后對(duì)RDD1執(zhí)行算子,獲取到RDD2命斧,然后再計(jì)算田晚,得到RDD3
默認(rèn)情況下,多次對(duì)一個(gè)RDD執(zhí)行算子国葬,去獲取不同的RDD贤徒;都會(huì)對(duì)這個(gè)RDD以及之前的父RDD,全部重新計(jì)算一次汇四;讀取HDFS->RDD1->RDD2-RDD4這種情況接奈,是絕對(duì)絕對(duì),一定要避免的通孽,一旦出現(xiàn)一個(gè)RDD重復(fù)計(jì)算的情況序宦,就會(huì)導(dǎo)致性能急劇降低。
比如背苦,HDFS->RDD1-RDD2的時(shí)間是15分鐘互捌,那么此時(shí)就要走兩遍,變成30分鐘
另外一種情況行剂,從一個(gè)RDD到幾個(gè)不同的RDD秕噪,算子和計(jì)算邏輯其實(shí)是完全一樣的,結(jié)果因?yàn)槿藶榈氖韬雠鸱恚?jì)算了多次巢价,獲取到了多個(gè)RDD。
所以,建議采用以下方法可以?xún)?yōu)化:
第一壤躲,RDD架構(gòu)重構(gòu)與優(yōu)化盡量去復(fù)用RDD城菊,差不多的RDD,可以抽取稱(chēng)為一個(gè)共同的RDD碉克,供后面的RDD計(jì)算時(shí)凌唬,反復(fù)使用。
第二漏麦,公共RDD一定要實(shí)現(xiàn)持久化
持久化客税,也就是說(shuō),將RDD的數(shù)據(jù)緩存到內(nèi)存中/磁盤(pán)中撕贞,(BlockManager)更耻,以后無(wú)論對(duì)這個(gè)RDD做多少次計(jì)算,那么都是直接取這個(gè)RDD的持久化的數(shù)據(jù)捏膨,比如從內(nèi)存中或者磁盤(pán)中秧均,直接提取一份數(shù)據(jù)。
第三号涯,持久化目胡,是可以進(jìn)行序列化的
如果正常將數(shù)據(jù)持久化在內(nèi)存中,那么可能會(huì)導(dǎo)致內(nèi)存的占用過(guò)大链快,這樣的話誉己,也許,會(huì)導(dǎo)致OOM內(nèi)存溢出域蜗。
當(dāng)純內(nèi)存無(wú)法支撐公共RDD數(shù)據(jù)完全存放的時(shí)候巨双,就優(yōu)先考慮,使用序列化的方式在純內(nèi)存中存儲(chǔ)地消。將RDD的每個(gè)partition的數(shù)據(jù)炉峰,序列化成一個(gè)大的字節(jié)數(shù)組,就一個(gè)對(duì)象脉执;序列化后疼阔,大大減少內(nèi)存的空間占用。
序列化的方式半夷,唯一的缺點(diǎn)就是婆廊,在獲取數(shù)據(jù)的時(shí)候,需要反序列化巫橄。
如果序列化純內(nèi)存方式淘邻,還是導(dǎo)致OOM,內(nèi)存溢出湘换;就只能考慮磁盤(pán)的方式宾舅,內(nèi)存+磁盤(pán)的普通方式(無(wú)序列化)统阿。內(nèi)存+磁盤(pán),序列化筹我。
第四扶平,為了數(shù)據(jù)的高可靠性,而且內(nèi)存充足蔬蕊,可以使用雙副本機(jī)制结澄,進(jìn)行持久化
持久化的雙副本機(jī)制,持久化后的一個(gè)副本岸夯,因?yàn)闄C(jī)器宕機(jī)了麻献,副本丟了,就還是得重新計(jì)算一次猜扮;持久化的每個(gè)數(shù)據(jù)單元勉吻,存儲(chǔ)一份副本,放在其他節(jié)點(diǎn)上面破镰;從而進(jìn)行容錯(cuò)餐曼;一個(gè)副本丟了,不用重新計(jì)算鲜漩,還可以使用另外一份副本。這種方式集惋,僅僅針對(duì)你的內(nèi)存資源極度充足孕似。
sessionid2actionRDD = sessionid2actionRDD.persist(StorageLevel.MEMORY_ONLY());
/**
- 持久化,很簡(jiǎn)單刮刑,就是對(duì)RDD調(diào)用persist()方法喉祭,并傳入一個(gè)持久化級(jí)別
- 如果是persist(StorageLevel.MEMORY_ONLY()),純內(nèi)存雷绢,無(wú)序列化泛烙,那么就可以用cache()方法來(lái)替代
- StorageLevel.MEMORY_ONLY_SER(),第二選擇
- StorageLevel.MEMORY_AND_DISK()翘紊,第三選擇
- StorageLevel.MEMORY_AND_DISK_SER()蔽氨,第四選擇
- StorageLevel.DISK_ONLY(),第五選擇
- 如果內(nèi)存充足帆疟,要使用雙副本高可靠機(jī)制
- 選擇后綴帶_2的策略
- StorageLevel.MEMORY_ONLY_2()
*/
sessionid2actionRDD = sessionid2actionRDD.persist(StorageLevel.MEMORY_ONLY());
參考閱讀
Spark核心編程:RDD持久化詳解
spark性能調(diào)優(yōu)之重構(gòu)RDD架構(gòu)鹉究,RDD持久化
Spark性能調(diào)優(yōu)之——在實(shí)際項(xiàng)目中重構(gòu)RDD架構(gòu)以及RDD持久化