2015-11-20 69 views
14

我正在通過這兩個概念,現在想要一些清晰。從工作到命令行,我一直試圖找出差異,以及開發人員何時使用重新分區與分區基準。Pyspark:分區與分區通過

下面是一些示例代碼:

rdd = sc.parallelize([('a', 1), ('a', 2), ('b', 1), ('b', 3), ('c',1), ('ef',5)]) 
rdd1 = rdd.repartition(4) 
rdd2 = rdd.partitionBy(4) 

rdd1.glom().collect() 
[[('b', 1), ('ef', 5)], [], [], [('a', 1), ('a', 2), ('b', 3), ('c', 1)]] 

rdd2.glom().collect() 
[[('a', 1), ('a', 2)], [], [('c', 1)], [('b', 1), ('b', 3), ('ef', 5)]] 

我看了看雙方的執行,唯一的區別我注意到大部分是partitionBy可以採取分區功能,或者使用portable_hash默認情況下。所以在partitionBy中,所有相同的鍵應該在同一個分區中。在重新分區中,我希望值可以更均勻地分佈在分區上,但事實並非如此。

鑑於此,爲什麼有人會使用重新分區?我想我能看到它被使用的唯一時間是如果我不使用PairRDD,或者我有大數據偏移?

有沒有我失蹤的東西,或有人可以從不同的角度爲我散光?

回答

7

repartition已經存在於RDD中,並且不處理按鍵(或除了排序以外的任何其他標準)的分區。現在,PairRDD添加了密鑰的概念,並隨後添加了另一種允許使用該密鑰進行分區的方法。所以,如果你的數據是鍵控的,你應該絕對使用該鍵進行分區,這在很多情況下是首先使用PairRDD的要點(對於連接,reduceByKey等)。

+1

那是什麼的重新分配不平均地分配元素的原因跨分區十歲上下?這可能是我沒有足夠數據的情況,我們遇到小樣本問題? –

+0

好問題,我在試用時看到了一個均勻分佈(在Scala中)。 –

+0

@JoeWiden沒有什麼比一個簡單的概率。 'repartition'實際上是通過在現有值中添加隨機密鑰來在內部使用RDD對,因此它不提供關於輸出數據分佈的有力保證。順便說一句你應該接受答案。 – zero323

6

重分區()用於指定考慮核心數量和數據量的分區數量。使用partitionBy()可以使洗牌功能更有效率,如reduceByKey(),join(),cogroup()等等。它只有在多次使用RDD的情況下才有好處,所以它是通常後面是persist()。

兩個在行動之間的區別:

pairs = sc.parallelize([1, 2, 3, 4, 2, 4, 1, 5, 6, 7, 7, 5, 5, 6, 4]).map(lambda x: (x, x)) 

pairs.partitionBy(3).glom().collect() 
[[(3, 3), (6, 6), (6, 6)], 
[(1, 1), (4, 4), (4, 4), (1, 1), (7, 7), (7, 7), (4, 4)], 
[(2, 2), (2, 2), (5, 5), (5, 5), (5, 5)]] 

pairs.repartition(3).glom().collect() 
[[(4, 4), (2, 2), (6, 6), (7, 7), (5, 5), (5, 5)], 
[(1, 1), (4, 4), (6, 6), (4, 4)], 
[(2, 2), (3, 3), (1, 1), (5, 5), (7, 7)]]