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
Performance 为什么要使用DataFrame.select而不是DataFrame.rdd.map(反之亦然)?_Performance_Apache Spark_Dataframe_Apache Spark Sql_Rdd - Fatal编程技术网

Performance 为什么要使用DataFrame.select而不是DataFrame.rdd.map(反之亦然)?

Performance 为什么要使用DataFrame.select而不是DataFrame.rdd.map(反之亦然)?,performance,apache-spark,dataframe,apache-spark-sql,rdd,Performance,Apache Spark,Dataframe,Apache Spark Sql,Rdd,在DataFrame上使用select来获取我们需要的信息和出于相同目的映射底层RDD的每一行之间是否存在“机械”区别 通过“机械”我指的是执行操作的机制。换句话说,实现细节 提供的两个选项中,哪一个性能更好/更高 df = # create dataframe ... df.select("col1", "col2", ...) 或 我在性能测试的中间,所以我要找出哪个更快,但我想知道什么是实现差异和优点/缺点。 < P> RDD只是一个转换和动作的图形谱系。 数据帧具有一个逻辑计划,该计划

DataFrame
上使用
select
来获取我们需要的信息和出于相同目的映射底层RDD的每一行之间是否存在“机械”区别

通过“机械”我指的是执行操作的机制。换句话说,实现细节

提供的两个选项中,哪一个性能更好/更高

df = # create dataframe ...
df.select("col1", "col2", ...)


我在性能测试的中间,所以我要找出哪个更快,但我想知道什么是实现差异和优点/缺点。

< P> RDD只是一个转换和动作的图形谱系。 数据帧具有一个逻辑计划,该计划在执行操作之前由Catalyst逻辑查询优化器进行内部优化

这对你来说意味着什么

如果您有DataFrame,那么您应该使用
选择
——任何额外的工作,如筛选、加入等,都将得到优化。优化的数据帧可以比普通RDD快10倍。换句话说,在执行
之前,select
Spark将尝试加快查询速度。使用dataFrame.rdd.map()时将不会执行此操作

还有一个:
rdd
值是通过执行以下操作惰性计算的:

lazy val rdd: RDD[T] = {
    val objectType = exprEnc.deserializer.dataType
    val deserialized = CatalystSerde.deserialize[T](logicalPlan)
    sparkSession.sessionState.executePlan(deserialized).toRdd.mapPartitions { rows =>
      rows.map(_.get(0, objectType).asInstanceOf[T])
    }
  }
因此Spark将使用其RDD、地图和演员阵容内容。两个版本的DAG在查询中几乎相同,所以性能相似。然而,在更高级的情况下,使用数据集的好处将非常明显,正如Spark PMCs在Databricks博客上写道的那样,使用Catalyst进行优化后,数据集的速度甚至可以提高100倍

请注意,DataFrame=Dataset[Row],它在后台使用RDD,但RDD图是在优化后创建的


注意:Spark是统一的API。Spark ML现在以数据帧为中心,不应使用旧API。流媒体正在向结构化流媒体转变。因此,即使在您的情况下不会有太多的性能改进,也可以考虑使用DATAFRAM。对于未来的开发,这将是一个更好的决策,当然比在这个过于简单的示例中使用普通RDD要快。选择和DataFrame.RDD.map,我认为差异几乎可以忽略不计

毕竟,您已经加载了数据集,并且只执行投影。最终,两者都必须从Spark的
InternalRow
列格式反序列化数据,以计算操作的结果

您可以通过
DataFrame检查发生了什么。通过
explain(extended=true)
选择

将物理计划(即
SparkPlan
)与您正在使用
rdd.map
(通过
toDebugString
)执行的操作进行比较,您将知道什么可能“更好”

scala>spark.range(5).rdd.toDebugString
res5:字符串=
(4) 在rdd处的MapPartitionsRDD[8]在:24[]
|rdd处的MapPartitionsRDD[7]位于:24[]
|rdd处的MapPartitionsRDD[6]位于:24[]
|rdd处的MapPartitionsRDD[5]位于:24[]
|在rdd处的并行采集rdd[4]在:24[]
(同样在这个人为的例子中,我认为没有赢家——两者都尽可能有效)

请注意,
DataFrame
实际上是一个
Dataset[Row]
,它使用
rowcoder
将数据编码(即序列化)为
InternalRow
列二进制格式。如果要在管道中执行更多的运算符,那么使用
Dataset
比使用
RDD
可以获得更好的性能,这仅仅是因为低级别的幕后逻辑查询计划优化和列式二进制格式

有很多优化,试图打败它们往往会浪费您的时间。为了获得更好的性能,您必须背诵Spark的内部结构(价格当然是可读性)

这其中有很多,我强烈建议观看赫尔曼·范·霍维尔的演讲,了解并欣赏所有的优化


我的看法是……“除非你知道自己在做什么,否则不要使用rdd”。

总之,
dataframe
操作总是比
rdd
对应操作快。@mtoto我不太确定。数据集必须序列化和反序列化数据,以便在类型化操作中处理+Scala代码,UDF可能会使优化消失(这对RDD来说并不“危险”。@JacekLaskowski数据集中的坏代码可能比RDD中的好代码慢;)然而,Dataset比普通RDD更快的次数更多。请注意Spark、ML和Streaming中的新API将以数据集为中心
lazy val rdd: RDD[T] = {
    val objectType = exprEnc.deserializer.dataType
    val deserialized = CatalystSerde.deserialize[T](logicalPlan)
    sparkSession.sessionState.executePlan(deserialized).toRdd.mapPartitions { rows =>
      rows.map(_.get(0, objectType).asInstanceOf[T])
    }
  }
scala> spark.version
res4: String = 2.1.0-SNAPSHOT

scala> spark.range(5).select('id).explain(extended = true)
== Parsed Logical Plan ==
'Project [unresolvedalias('id, None)]
+- Range (0, 5, step=1, splits=Some(4))

== Analyzed Logical Plan ==
id: bigint
Project [id#17L]
+- Range (0, 5, step=1, splits=Some(4))

== Optimized Logical Plan ==
Range (0, 5, step=1, splits=Some(4))

== Physical Plan ==
*Range (0, 5, step=1, splits=Some(4))
scala> spark.range(5).rdd.toDebugString
res5: String =
(4) MapPartitionsRDD[8] at rdd at <console>:24 []
 |  MapPartitionsRDD[7] at rdd at <console>:24 []
 |  MapPartitionsRDD[6] at rdd at <console>:24 []
 |  MapPartitionsRDD[5] at rdd at <console>:24 []
 |  ParallelCollectionRDD[4] at rdd at <console>:24 []