Spark RDD Partition

1、概念

 RDD內部並行計算的計算單元。儘可能規避Shuffle過程,降低網絡開銷。

 RDD的數據集在邏輯上被劃分爲多個分片,每一個分片成爲分區,分區的格式決定了並行計算的粒度。每個分區的數值計算都是在一個任務中進行的,因此任務的個數是由RDD(準確來說是作業最後一個RDD)的分區數決定的。

2、原理

 MapReduce裏面的網絡傳輸主要在Shuffle階段,Shuffle的根本原因是相同的key存在不同的節點上,按key進行聚合的時候不得不進行Shuffle。

 Spark把key-value RDD通過key的hashcode進行分區,而且保證相同的key存儲在同一個節點上,這樣對該RDD進行key聚合時,就不需要Shuffle過程。

 key的分佈不均決定了有的分區大有的分區小,沒法保證分區完全相等,但它會保證在一個接近的範圍。

 進行join的時候是兩個表,不可能把兩個表都分區好,通常情況下是把用的頻繁的大表事先進行分區,小表進行關聯它的時候,小表進行Shuffle過程,大表不需要Shuffle。

3、算子
1)能從分區中獲益的算子

 cogroup(), groupWith(), join(), leftOuterJoin(), rightOuterJoin(), groupByKey(), reduceByKey(), combineByKey(), lookup().

2)能影響結果RDD分區方式的算子

 Spark內部知道各個操作的影響分區方式,並將會對數據進行分區的操作的結果RDD自動設置對應的分區器。

 cogroup(), groupWith(), join(), leftOuterJoin(), rightOuterJoin(), groupByKey(), reduceByKey(), combineByKey(), partitionBy(), sort(), mapValues()(若父RDD已有分區方式的話), flatMapValues()(若), filter()(若)。

 其他所有操作生成的結果都不會存在特定的分區方式。

4、機制
1)分區原則

 儘可能使分區的個數等於集羣核心數目。

 儘可能使同一RDD不同分區內的記錄數量一致。

2)分區策略

[1]HashPartitioner

[2]RangePartitioner

[3]Custom:

 擴展Partitioner抽象類,實現裏面的三個方法:

 def numPartitions: Int: 這個方法需要返回你想要創建分區的個數

 def getPartition(key: Any): Int: 這個函數需要對輸入的key做計算,然後返回該key的分區id,範圍一定是0到numPartitions-1

 def equals(other: Any): Boolean: 這個是Java標準的判斷相等的函數,之所以要求用戶實現這個函數是因爲Spark內部會比較兩個RDD的分區是否一樣。

3)分區記錄個數

對於轉換操作得到的RDD:

 如果是窄依賴,則分區記錄數量依賴於父RDD中相同編號分區的數據分配方式。

 如果是寬依賴,則分區記錄數量依賴於選擇的分區器,哈希分區器無法保證數據被平均分配到各個分區,範圍分區器可以保證。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章