我正在使用Spark的Python API并运行Spark 0.8。
我正在存储一个大的RDD浮点向量,我需要对整个集合执行一个向量的计算。
RDD中的切片和分区之间有什么区别吗?
当我创建RDD时,我将其作为参数传递100,这使得它将RDD存储为100个切片并在执行计算时创建100个任务。我想知道,通过使系统更有效地处理数据(即,在分区上执行操作与仅仅操作切片RDD中的每个元素之间存在差异),分区数据是否会提高切片之外的性能。 / p>
例如,这两段代码之间是否有任何显着差异?
rdd = sc.textFile(demo.txt, 100)
VS
rdd = sc.textFile(demo.txt)
rdd.partitionBy(100)
答案 0 :(得分:24)
我认为slices
和partitions
在Apache Spark中是相同的。
但是,您发布的两段代码之间存在微妙但可能存在显着差异。
此代码将尝试使用100个并发任务将demo.txt
直接加载到100个分区中:
rdd = sc.textFile('demo.txt', 100)
对于未压缩的文本,它将按预期工作。但是如果不是demo.txt
而是demo.gz
,那么最终只会有一个分区的RDD。对gzip压缩文件的读取无法并行化。
另一方面,以下代码首先将demo.txt
打开到具有默认分区数的RDD中,然后它将显式地将数据重新分区为100个大致相等的分区大小。
rdd = sc.textFile('demo.txt')
rdd = rdd.repartition(100)
所以在这种情况下,即使使用demo.gz
,您最终也会得到一个包含100个分区的RDD。
作为旁注,我已将partitionBy()
替换为repartition()
,因为这是我认为您正在寻找的内容。 partitionBy()
要求RDD是元组的RDD。由于{0.8}中没有repartition()
,因此您应该可以使用coalesce(100, shuffle=True)
。
Spark可以为RDD的每个分区运行1个并发任务,最多可以为集群中的核心数量。因此,如果您有一个包含50个内核的群集,您希望您的RDD至少有50个分区(可能2-3x times that)。
从Spark 1.1.0开始,您可以查看RDD具有的分区数量如下:
rdd.getNumPartitions() # Python API
rdd.partitions.size // Scala API
在1.1.0之前,使用Python API执行此操作的方法是rdd._jrdd.splits().size()
。
答案 1 :(得分:2)
您可以按如下方式进行分区:
import org.apache.spark.Partitioner
val p = new Partitioner() {
def numPartitions = 2
def getPartition(key: Any) = key.asInstanceOf[Int]
}
recordRDD.partitionBy(p)