Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark Dataset.rdd是操作还是转换?_Apache Spark_Apache Spark Sql - Fatal编程技术网

Apache spark Dataset.rdd是操作还是转换?

Apache spark Dataset.rdd是操作还是转换?,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,评估数据帧是否为空的方法之一是执行df.rdd.isEmpty(),但是,我在sparkUI执行中看到mycode.scala:123处的rdd。这让我想知道这个rdd()函数是否实际上是一个动作,而不是一个转换 我知道isEmpty()是一个动作,但我确实看到mycode.scala:234的isEmpty()有一个单独的阶段,所以我认为它们是不同的动作?rdd是用“rdd术语”来表示结构化查询的,所以Spark可以执行它。它是您的类型T的JVM对象的RDD。如果使用不当,可能会导致内存问题,

评估数据帧是否为空的方法之一是执行
df.rdd.isEmpty()
,但是,我在sparkUI执行中看到mycode.scala:123处的
rdd。这让我想知道这个rdd()函数是否实际上是一个动作,而不是一个转换


我知道isEmpty()是一个动作,但我确实看到mycode.scala:234的isEmpty()有一个单独的阶段,所以我认为它们是不同的动作?

rdd
是用“rdd术语”来表示结构化查询的,所以Spark可以执行它。它是您的类型
T
的JVM对象的RDD。如果使用不当,可能会导致内存问题,因为:

  • 将位于JVM外部的内部管理的优化行传输到JVM中的内存空间

  • 将二进制行转换为业务对象(JVM“true”表示)

  • 前者将增加计算所需的JVM内存,而后者是一个额外的转换步骤

    对于这样一个计算行数的简单计算,您宁愿坚持使用
    count
    作为优化且相当便宜的计算(这可以避免复制对象和应用模式)

    在内部,
    Dataset
    将行保留在其
    InternalRow
    中。这降低了Spark应用程序的JVM内存需求。计算RDD(来自
    RDD
    )以表示火花动作执行后将执行的火花变换

    请注意,执行
    rdd
    会创建一个rdd,并且也需要一些计算

    因此,是的,
    rdd
    在“执行”查询时可能被视为一个操作(即位于后面的数据集的物理计划),但最终它只给出了一个
    rdd
    (因此,根据定义,它不能是一个操作,因为Spark actions返回一个非rdd值)

    如图所示:

    比较下面的RDD谱系,并思考哪一个看起来更好

    val dataset = spark.range(5).withColumn("group", 'id % 2)
    scala> dataset.rdd.toDebugString
    res1: String =
    (8) MapPartitionsRDD[8] at rdd at <console>:26 [] // <-- extra deserialization step
     |  MapPartitionsRDD[7] at rdd at <console>:26 []
     |  MapPartitionsRDD[6] at rdd at <console>:26 []
     |  MapPartitionsRDD[5] at rdd at <console>:26 []
     |  ParallelCollectionRDD[4] at rdd at <console>:26 []
    
    // Compare with a more memory-optimized alternative
    // Avoids copies and has no schema
    scala> dataset.queryExecution.toRdd.toDebugString
    res2: String =
    (8) MapPartitionsRDD[11] at toRdd at <console>:26 []
    |  MapPartitionsRDD[10] at toRdd at <console>:26 []
    |  ParallelCollectionRDD[9] at toRdd at <console>:26 []
    
    正如您在(上面粘贴的)中所看到的,最后请求
    rdd
    将触发一个额外的计算来获取rdd

  • 创建一个新的逻辑计划来反序列化数据集的逻辑计划,即从JVM外部管理的内部二进制行格式中获得额外的反序列化,以其对应的表示形式表示为JVM内的JVM对象(想想你应该不惜一切代价避免的GC)

  • 谢谢你的解释,我还有一个问题,count()也是一个动作,必须计算所有行。虽然rdd.isEmpty()只执行take(1),所以在这种情况下可能会更快,对吗?@linehrr添加了关于rdd的新部分。如果你还需要什么,请告诉我。让我们消除所有的疑虑!快乐火花!:)
    df.queryExecution.toRdd.isEmpty
    
    val dataset = spark.range(5).withColumn("group", 'id % 2)
    scala> dataset.rdd.toDebugString
    res1: String =
    (8) MapPartitionsRDD[8] at rdd at <console>:26 [] // <-- extra deserialization step
     |  MapPartitionsRDD[7] at rdd at <console>:26 []
     |  MapPartitionsRDD[6] at rdd at <console>:26 []
     |  MapPartitionsRDD[5] at rdd at <console>:26 []
     |  ParallelCollectionRDD[4] at rdd at <console>:26 []
    
    // Compare with a more memory-optimized alternative
    // Avoids copies and has no schema
    scala> dataset.queryExecution.toRdd.toDebugString
    res2: String =
    (8) MapPartitionsRDD[11] at toRdd at <console>:26 []
    |  MapPartitionsRDD[10] at toRdd at <console>:26 []
    |  ParallelCollectionRDD[9] at toRdd at <console>:26 []
    
    rdd: RDD[T]