編寫Spark程序的幾個優(yōu)化點

雖然spark已經(jīng)提供了大量簡單易用的API左胞,但要想編寫出高性能的spark應(yīng)用担钮,必須要對整體框架有一定的了解,對于Spark初學(xué)者來說是比較困難的厚棵。

針對這個這個問題蕉世,其實在spark1.6中,已經(jīng)加入了dataset婆硬,官方已經(jīng)對其進行了一系列的優(yōu)化狠轻,用戶可以將rdd轉(zhuǎn)化為dataset操作,減少學(xué)習(xí)成本彬犯。不過目前(1.6版本)依舊存在一些bug向楼。

下文講解了使用RDD編程時,常用的幾種代碼優(yōu)化方法谐区。

1. repartition和coalesce

這兩個方法都可以用在對數(shù)據(jù)的重新分區(qū)中蜜自,其中repartition是一個代價很大的操作,它會將所有的數(shù)據(jù)進行一次shuffle卢佣,然后重新分區(qū)重荠。

如果你僅僅只是想減少分區(qū)數(shù),從而達到減少碎片任務(wù)或者碎片數(shù)據(jù)的目的虚茶。使用coalesce就可以實現(xiàn)戈鲁,該操作默認(rèn)不會進行shuffle。其實repartition只是coalesce的shuffle版本嘹叫。

一般我們會在filter算子過濾了大量數(shù)據(jù)后使用它婆殿。比如將 partition 數(shù)從1000減少到100。這可以減少碎片任務(wù)罩扇,降低啟動task的開銷婆芦。

note1: 如果想查看當(dāng)前rdd的分區(qū)數(shù),在java/scala中可以使用rdd.partitions.size()喂饥,在python中使用rdd.getNumPartitions()消约。

note2: 如果要增加分區(qū)數(shù),只能使用repartition,或者把partition縮減為一個非常小的值员帮,比如說“1”或粮,也建議使用repartition。

2. mapPartitions和foreachPartitions

適當(dāng)使用mapPartitionsforeachPartitions代替mapforeach可以提高程序運行速度捞高。這類操作一次會處理一個partition中的所有數(shù)據(jù)氯材,而不是一條數(shù)據(jù)渣锦。

mapPartition - 因為每次操作是針對partition的,那么操作中的很多對象和變量都將可以復(fù)用氢哮,比如說在方法中使用廣播變量等袋毙。

foreachPartition - 在和外部數(shù)據(jù)庫交互操作時使用,比如 redis , mysql 等冗尤。通過該方法可以避免頻繁的創(chuàng)建和銷毀鏈接听盖,每個partition使用一個數(shù)據(jù)庫鏈接,對效率的提升還是非常明顯的生闲。

note: 此類方法也存在缺陷媳溺,因為一次處理一個partition中的所有數(shù)據(jù)月幌,在內(nèi)存不足的時候碍讯,將會遇到OOM的問題。

3.reduceByKey和aggregateByKey

使用reduceByKey/aggregateByKey代替groupByKey扯躺。

reduceByKey/aggregateByKey會先在map端對本地數(shù)據(jù)按照用戶定義的規(guī)則進行一次聚合捉兴,之后再將計算的結(jié)果進行shuffle,而groupByKey則會將所以的計算放在reduce階段進行(全量數(shù)據(jù)在各個節(jié)點中進行了分發(fā)和傳輸)录语。所以前者的操作大量的減少shuffle的數(shù)據(jù)倍啥,減少了網(wǎng)絡(luò)IO,提高運行效率澎埠。

4. mapValues

針對k,v結(jié)構(gòu)的rdd虽缕,mapValues直接對value進行操作,不對Key造成影響蒲稳,可以減少不必要的分區(qū)操作氮趋。

5. broadcast

Spark中廣播變量有幾個常見的用法。

  1. 實現(xiàn)map-side join

    在需要join操作時江耀,將較小的那份數(shù)據(jù)轉(zhuǎn)化為普通的集合(數(shù)組)進行廣播剩胁,然后在大數(shù)據(jù)集中使用小數(shù)據(jù)進行相應(yīng)的查詢操作,就可以實現(xiàn)map-side join的功能祥国,避免了join操作的shuffle過程昵观。在我之前的文章中對此用法有詳細說明和過程圖解。

  2. 使用較大的外部變量

    如果存在較大的外部變量(外部變量可以理解為在driver中定義的變量)舌稀,比如說字典數(shù)據(jù)等啊犬。在運算過程中,會將這個變量復(fù)制出多個副本壁查,傳輸?shù)矫總€task之中進行執(zhí)行椒惨。如果這個變量的大小有100M或者更大,將會浪費大量的網(wǎng)絡(luò)IO潮罪,同時康谆,executor也會因此被占用大量的內(nèi)存领斥,造成頻繁GC,甚至引發(fā)OOM沃暗。

    因此在這種情況下月洛,我最好提前對該變量進行廣播,它會被事先將副本分發(fā)到每個executor中孽锥,同一executor中的task則在執(zhí)行時共享該變量嚼黔。很大程度的減少了網(wǎng)絡(luò)IO開銷以及executor的內(nèi)存使用。

6. 復(fù)用RDD

避免創(chuàng)建一些用處不大的中間RDD(比如從父RDD抽取了某幾個字段形成新的RDD)惜辑,這樣可以減少一些算子操作唬涧。

對多次使用的RDD進行緩存操作,減少重復(fù)計算盛撑,在下文有說明碎节。

7. cache和persist

cache方法等價于persist(StorageLevel.MEMORY_ONLY)

不要濫用緩存操作。緩存操作非常消耗內(nèi)存抵卫,緩存前考慮好是否還可以對一些無關(guān)數(shù)據(jù)進行過濾狮荔。如果你的數(shù)據(jù)在接下來的操作中只使用一次,則不要進行緩存介粘。

如果需要復(fù)用RDD殖氏,則可以考慮使用緩存操作,將大幅度提高運行效率姻采。緩存也分幾個級別雅采。

  • MEMORY_ONLY

    如果緩存的數(shù)據(jù)量不大或是內(nèi)存足夠,可以使用這種方式慨亲,該策略效率是最高的婚瓜。但是如果內(nèi)存不夠,之前緩存的數(shù)據(jù)則會被清出內(nèi)存巡雨。在spark1.6中闰渔,則會直接提示OOM。

  • MEMORY_AND_DISK

    優(yōu)先將數(shù)據(jù)寫入內(nèi)存铐望,如果內(nèi)存不夠則寫入硬盤冈涧。較為穩(wěn)妥的策略,但是如果不是很復(fù)雜的計算正蛙,可能重算的速度比從磁盤中讀取還要快督弓。

  • MEMORY_ONLY_SER

    會將RDD中的數(shù)據(jù)序列化后存入內(nèi)存,占用更小的內(nèi)存空間乒验,減少GC頻率愚隧,當(dāng)然,取出數(shù)據(jù)時需要反序列化锻全,同樣會消耗資源狂塘。

  • MEMORY_AND_DISK_SER

    不再贅述录煤。

  • DISK_ONLY

    該策略類似于checkPoint方法,把所有的數(shù)據(jù)存入了硬盤荞胡,再使用的時候從中讀出妈踊。適用于數(shù)據(jù)量很大,重算代價也非常高的操作泪漂。

  • 各種_2結(jié)尾的存儲策略

    實際上是對緩存的數(shù)據(jù)做了一個備份廊营,代價非常高,一般不建議使用萝勤。

結(jié)語

spark的優(yōu)化方法還有很多露筒,這篇文章主要從使用的角度講解了常用的優(yōu)化方法,具體的使用方法可以參考博主的其他優(yōu)化文章敌卓。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末慎式,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子假哎,更是在濱河造成了極大的恐慌瞬捕,老刑警劉巖鞍历,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舵抹,死亡現(xiàn)場離奇詭異,居然都是意外死亡劣砍,警方通過查閱死者的電腦和手機惧蛹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刑枝,“玉大人香嗓,你說我怎么就攤上這事∽俺” “怎么了靠娱?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長掠兄。 經(jīng)常有香客問我像云,道長,這世上最難降的妖魔是什么蚂夕? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任迅诬,我火速辦了婚禮,結(jié)果婚禮上婿牍,老公的妹妹穿的比我還像新娘侈贷。我一直安慰自己,他們只是感情好等脂,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布俏蛮。 她就那樣靜靜地躺著撑蚌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪搏屑。 梳的紋絲不亂的頭發(fā)上锨并,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機與錄音睬棚,去河邊找鬼第煮。 笑死,一個胖子當(dāng)著我的面吹牛抑党,可吹牛的內(nèi)容都是我干的包警。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼底靠,長吁一口氣:“原來是場噩夢啊……” “哼害晦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起暑中,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤壹瘟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鳄逾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體稻轨,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年雕凹,在試婚紗的時候發(fā)現(xiàn)自己被綠了殴俱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡枚抵,死狀恐怖线欲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情汽摹,我是刑警寧澤李丰,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站逼泣,受9級特大地震影響趴泌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜圾旨,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一踱讨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧砍的,春花似錦痹筛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谣旁。三九已至,卻和暖如春滋早,著一層夾襖步出監(jiān)牢的瞬間榄审,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工杆麸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留搁进,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓昔头,卻偏偏與公主長得像饼问,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子揭斧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容