對spark中RDD的partition通俗易懂的介紹
在簡書上看到一個介紹,很喜歡,確實一看懂。
我們要想對spark中RDD的分割槽進行一個簡單的瞭解的話,就不免要先了解一下hdfs的前世今生 (放心,hdfs的前世今生很短)。
眾所周知,hdfs是一個非常不錯的分散式檔案系統,這是這麼多年來大家有目共睹的。
hdfs檔案為分散式儲存,每個檔案都被切分為block(預設為128M)。為了達到容錯的目的,他們還提供為每個block存放了N個副本(預設為3個)。當然,以上說的這些也可以根據實際的環境業務調整。
多副本除了可以達到容錯的目的,也為計算時資料的本地性提供了便捷。當資料所在節點的計算資源不充足時,多副本機制可以不用遷移資料,直接在另一個副本所在節點計算即可。此時看到這裡,肯定就有人會問了,那如果所有副本所在的節點計算資源都不充足那該怎麼辦?
問的很好,一般會有一個配置來設定一個等待時長來等待的,假設等待時長為三秒,如果超過三秒,還沒有空閒資源,就會分配給別的副本所在節點計算的,如果再別的副本所在節點也需等待且超過了三秒。則就會啟動資料遷移了(諸多因素影響,代價就比較大了)。
接下來我們就介紹RDD,RDD是什麼?彈性分散式資料集。
彈性:並不是指他可以動態擴充套件,而是。
分散式:顧名思義,RDD會在多個節點上儲存,就和hdfs的分散式道理是一樣的。hdfs檔案被切分為多個block儲存在各個節點上,而RDD是被切分為多個partition。不同的partition可能在不同的節點上。(這句話是本文最為核心的,詳情可以看下面,這裡partition和block不單單是類比,還有他們之間的聯絡,partition可以看做block的一個上層結構,下層有HDFS的block組成)
再spark讀取hdfs的場景下,spark把hdfs的block讀到記憶體就會抽象為spark的partition。至於後續遇到shuffle的操作,RDD的partition可以根據Hash再次進行劃分(一般pairRDD是使用key做Hash再取餘來劃分partition)。
再spark計算末尾,一般會把資料做持久化到hive,hbase,hdfs等等。我們就拿hdfs舉例,將RDD持久化到hdfs上,RDD的每個partition就會存成一個檔案,如果檔案小於128M,就可以理解為一個partition對應hdfs的一個block。反之,如果大於128M,就會被且分為多個block,這樣,一個partition就會對應多個block。
鑑於上述partition大於128M的情況,在做sparkStreaming增量資料累加時一定要記得調整RDD的分割槽數。假設,第一次儲存RDD時10個partition,每個partition有140M。那麼該RDD儲存在hdfs上就會有20個block,下一批次重新讀取hdfs上的這些資料,RDD的partition個數就會變為20個。再後續有類似union的操作,導致partition增加,但是程式有沒有repartition或者進過shuffle的重新分割槽,這樣就導致這部分資料的partition無限增加,這樣一直下去肯定是會出問題的。所以,類似這樣的情景,再程式開發結束一定要審查需不需要重新分割槽。