RDD的切片和分区之间有什么区别?

时间:2014-06-17 17:01:05

标签: python apache-spark

我正在使用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)

2 个答案:

答案 0 :(得分:24)

我认为slicespartitions在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)