根据学习星火
请记住,重新分区的数据是一个相当昂贵的操作。 火花也有再分配的优化版本()呼吁COALESCE(),允许避免数据移动,但只有当你正在减少RDD分区的数量。
一个不同之处,我得到的是与再分配()分区的数量可以增加/减少,但与COALESCE()分区的数量只能减少。
如果分区在多台机器和接合()运行蔓延,如何能够避免数据移动?
根据学习星火
请记住,重新分区的数据是一个相当昂贵的操作。 火花也有再分配的优化版本()呼吁COALESCE(),允许避免数据移动,但只有当你正在减少RDD分区的数量。
一个不同之处,我得到的是与再分配()分区的数量可以增加/减少,但与COALESCE()分区的数量只能减少。
如果分区在多台机器和接合()运行蔓延,如何能够避免数据移动?
它避免了全面洗牌。 如果它知道的数量正在减少,则遗嘱执行人可以安全地保持对分区的最小数量的数据,仅移动数据关闭额外的节点,在我们不断的节点。
因此,它会去是这样的:
Node 1 = 1,2,3
Node 2 = 4,5,6
Node 3 = 7,8,9
Node 4 = 10,11,12
然后coalesce
到2个分区:
Node 1 = 1,2,3 + (10,11,12)
Node 3 = 7,8,9 + (4,5,6)
请注意,节点1和节点3并不需要原来的数据移动。
贾斯汀的答案是真棒,这种反应将进入更深入。
在repartition
算法做了充分洗牌,并创建与同时均匀分布数据的新分区。 让我们创建一个数字的数据帧从1到12。
val x = (1 to 12).toList
val numbersDf = x.toDF("number")
numbersDf
包含在我的机器上的4个分区。
numbersDf.rdd.partitions.size // => 4
下面是数据是如何在分区划分:
Partition 00000: 1, 2, 3
Partition 00001: 4, 5, 6
Partition 00002: 7, 8, 9
Partition 00003: 10, 11, 12
让我们做了充分的洗牌与repartition
方法,并获得两个节点这个数据。
val numbersDfR = numbersDf.repartition(2)
下面是如何numbersDfR
数据在我的机器上的划分:
Partition A: 1, 3, 4, 6, 7, 9, 10, 12
Partition B: 2, 5, 8, 11
所述repartition
方法使得新的分区和均匀地分布在新分区中的数据(数据分配是即使对于更大的数据集更多)。
区别coalesce
和repartition
coalesce
现有的分区,以尽量减少洗牌真实的数据量使用。 repartition
创建新分区,并做了充分洗牌。 coalesce
在用不同量的数据(有时具有多不同的尺寸分区)和分区结果repartition
结果大致相等大小的分区。
是coalesce
或repartition
更快?
coalesce
可能会运行速度比repartition
,但不等大小的分区一般是慢于同等大小的分区的工作。 您通常需要筛选大量数据集后重新分区的数据集。 我发现repartition
,因为星火是建立与同等大小的分区合作,以更快的整体。
阅读这篇博客 ,如果你想更详细信息。
一个额外这里要注意的是,作为星火的基本原则是RDD不变性。 重新分区或聚结将创造新的RDD。 该基地RDD将继续存在,其原有的分区数目。 如果用例需要坚持RDD在高速缓存中,然后同样具有新创建RDD工作要做。
scala> pairMrkt.repartition(10)
res16: org.apache.spark.rdd.RDD[(String, Array[String])] =MapPartitionsRDD[11] at repartition at <console>:26
scala> res16.partitions.length
res17: Int = 10
scala> pairMrkt.partitions.length
res20: Int = 2
所有的答案都增加了一些伟大的知识,这个经常被问到的问题。
因此,通过这个问题的时间表的传统去,这里是我的2美分。
我找到了重新分区比聚结快 ,在非常特殊的情况下。
在我的应用程序时,我们估计的文件数超过一定的阈值,重新划分工作速度更快。
这里是我的意思
if(numFiles > 20)
df.coalesce(numFiles).write.mode(SaveMode.Overwrite).parquet(dest)
else
df.repartition(numFiles).write.mode(SaveMode.Overwrite).parquet(dest)
在上面的代码,如果我的文件均小于20,聚结正在采取永远结束而重新分区是更快,所以上面的代码。
当然,这个数字(20)将依赖于数据的工人的数量和金额。
希望帮助。
在一个简单的方法COALESCE: - 仅用于降低无分区,数据的不洗牌,它只是压缩分区
再分配: - 是增能减的没有分区的,但是洗牌发生
例:-
val rdd = sc.textFile("path",7)
rdd.repartition(10)
rdd.repartition(2)
这两个工作正常
但是,我们一般去这两个东西的时候,我们需要看到输出一个集群,我们去与此有关。
repartition
-它推荐使用的重新分配,同时增加不分区的,因为它涉及到所有的数据交换。
coalesce
-这是建议使用聚结,同时减少不分区。 例如,如果你有3个分区,并希望将其减少到2个分区,合并将第3分区中的数据移动到分区1和2,分区1和2保持在同一Container.but再分配将在这样的网络使用所有分区的数据洗牌执行者之间将是高,它会影响性能。
性能方面coalesce
不是性能更好的repartition
,同时减少不分区。
但是,你也应该确保,这是未来的聚结节点的数据应该高度配置,如果你正在处理大量的数据。 因为所有的数据将被加载到这些节点,可能会导致内存异常。 虽然赔偿是昂贵的,我更喜欢使用它。 因为它打乱,并平均分配数据。
是明智的结合并重新分配之间进行选择。
我想补充的贾斯汀和电源的答案是 -
“重新分配”会忽略现有的分区并创建新的。 所以,你可以用它来解决数据偏移。 你可以提分区键来改变分配。 数据偏移是在“大数据”问题空间的最大问题之一。
“合并”将与现有的分区工作,他们洗牌的一个子集。 它不能修复数据扭曲不亚于“再分配”即可。 所以即使是更便宜的它那下跪是你需要的东西。
所有伟大的答案,我想补充一点,重新分区是一个利用数据并行化和聚结的最好的选择提供了廉价的选择写入数据时,HDFS或其他一些沉到利用,以减少分区非常有用大写入。 在实木复合地板格式写入数据时得到充分利用我发现这非常有用。