1.1避免建立重複RDD數組
一般指,在開發spark做業中,首先基於某個數據源,(如hive或hdfs文件)建立一個初始RDD,接着對這個RDD進行某個算子操做,而後獲得下一個RDD,以此類推,循環往復,直到計算出咱們須要的結果;在此過程當中多個RDD會經過不一樣算子操做串起來。這個RDD串 `RDD lineage` 也就是RDD的血緣關係鏈。緩存
**在咱們開發中注意,對於同一份數據,只建立一個RDD,不能建立多個RDD來表明同一份據。網絡
1.2儘量複用同一個RDDjvm
1.咱們除了在開發中避免對同一份徹底相同數據建立多個RDD以外,與此同時在數據執行算子還要儘量複用一個RDD;性能
2.好比有一個RDD數據格式爲k-v類型,另外一個是單v類型,這兩個RDD的value數據徹底同樣,那麼此時咱們能夠只使用k-v類型的那個RDD,由於其中已經包含了另外一個的數據,對於相似這種多個RDD有重疊或包含的狀況,咱們儘可能複用一個RDD,這樣能夠減小算子執行次數,也能夠減小RDD的數量。 優化
1.3對於屢次使用RDD進行持久化spa
1.3.1概述對象
1.當咱們在spark代碼中屢次對一個RDD作算子操做後,就實現了spark做業的第一步優化,也便是儘量複用RDD,此時就該在這個基礎之上進行第二步優化,blog
也就是保證對一個RDD進行執行屢次算子操做時,這個RDD自己僅僅被計算一次。內存
2.spark中對於一個RDD執行屢次算子的默認原理是這樣,每次你對一個RDD執行一個算子操做時,都會從新從源頭計算一遍,計算出那個RDD來而後進行對這個RDD執行你的算子操做,這種方式性能不好的。
3.所以對於這種狀況,咱們建議是對屢次使用RDD進行持久化,此時spark會根據你的持久化策略,將RDD中數據保存到內存或磁盤中,之後每次對這個RDD進行算子操做時,都會直接從內存或磁盤中提取持久化的RDD數據,而後執行算子,而不會從源頭從新計算一遍這個RDD,再執行算子操做。
1.3.2持久化策略
1.3.3選擇合適的持久化策略
1.默認狀況下,性能最高固然是MEMORY_ONLY,可是前提是你的內存足夠大,能夠綽綽有餘存放整個RDD的全部數據由於不進行序列化和反序列化操做就避免了這部分的性能開銷;對這個RDD的後續算子操做都是基於內存的數據操做,不須要從磁盤文件中讀取數據,性能也很高,並且不須要複製一份數據副本,並遠程傳送到其餘節點上。可是這裏必需要注意的是實際的生產環境恐怕可以直接用這種策略場景有限,若是RDD中數據比較多時,直接用這種持久化級別,會致使jvmdeOOM內存溢出異常。
2.若是使用MEMORY_ONLI級別時發生內存溢出,那麼建議嘗試使用MEMORY_ONLY_SER級別,該級別會將RDD數據序列化後再保存內存中,此時每一個partition僅僅是一個字節數組而已,大大減小對象數量,並下降內存佔用,這種級別比MEMORY_ONLY多出來性能開銷,主要就是序列化和反序列化的開銷,但後續算子能夠基於純內存進行操做,所以性能整體來講仍是比較高的,此外可能發生的問題同上,若是RDD中數量過多的話,仍是可能致使OOM異常。
3.若是純內存級別都沒法使用,而不MEMORY_AND_DISK策略,由於既然到了這一步就是說明RDD數據量大,內存沒法徹底放下,序列化後的數據比較少,能夠節省內存和磁盤空間開銷,同時該策略會優先儘可能數據比較少,能夠節省內存和磁盤空間開銷,同時該策略會優先儘可能嘗試將數據緩存內存中,內存緩存不下會寫入磁盤。
4.一般不建議使用DISK_ONLY和後綴爲2的級別,由於徹底基於磁盤文件進行數據讀寫,會致使性能急劇下降,有時還不如從新計算一次全部RDD,後綴爲2級別,必須將全部數據都複製一份副本,而且發送到其它節點上,數據複製以及網絡傳輸會致使較大性能開銷,除非要求做業高可用性,不然不建議使用。
1.3.4 gc回收過程