Spark RDD的take(1)和first()之间的区别

Ida*_*Ida 10 apache-spark rdd pyspark

我曾经认为rdd.take(1)并且rdd.first()完全一样.然而,在我的同事向我指出Spark关于RDD的裁决文件后,我开始怀疑这是否真的如此:

first():返回此RDD中的第一个元素.

take(num):获取RDD的前几个num元素.它的工作原理是首先扫描一个分区,然后使用该分区的结果来估计满足限制所需的其他分区数.

我的问题是:

  1. 底层实现是first()一样的take(1)吗?
  2. 假设rdd1并且rdd2由相同的csv构造,我可以安全地假设rdd1.take(1)并且rdd2.first()始终返回相同的结果,即csv的第一行吗?如果rdd1rdd2分区不同怎么办?

Pra*_*kla 17

Infact first以实现方式实现take.

以下是来自Spark的RDD.scala来源.first调用take(1)并返回第一个元素(如果找到).

  def first(): T = withScope {
    take(1) match {
      case Array(t) => t
      case _ => throw new UnsupportedOperationException("empty collection")
    }
  }
Run Code Online (Sandbox Code Playgroud)

take(num)尝试从RDD的第0个分区开始获取num元素(如果考虑基于0的索引).所以take(1)和first的行为是相同的.

即使是火花编程指南也证实了这一点.

关于你的第二个问题:当你说区别不同时,这取决于你的意思.如果您sc.textFile("/path/to/file")使用或不使用numPartitions 进行调用,则无关紧要,因为第0个分区将始终为第0个分区.所以,是的,您可以假设它们具有相同的第一个元素.

编辑:RDD中的分区是有序的,CSV中的物理第一行将在RDD的第0个分区中结束.而take(1)first这两个将回到零分区的是第一排.


Ami*_*mar 5

两者都不相同.

rdd.first()将返回此RDD中的第一个元素,同时rdd.take(1)返回仅具有第一个元素的数组.

  1. first()的底层实现与take(1)相同吗?

Ans:在实现方面,first()在内部调用take(1)并返回第一个而且只返回take(1)返回的数组元素.取自org.apache.spark.rdd.RDD类

  /**
   * Return the first element in this RDD.
   */
  def first(): T = withScope {
    take(1) match {
      case Array(t) => t
      case _ => throw new UnsupportedOperationException("empty collection")
    }
  }
Run Code Online (Sandbox Code Playgroud)
  1. 假设rdd1和rdd2是从相同的csv构造的,我可以安全地假设rdd1.take(1)和rdd2.first()将始终返回相同的结果,即csv的第一行吗?如果rdd1和rdd2的分区不同怎么办?

Ans:是的,您可以认为,分区不会改变读取输入的顺序.