我以为Spark数据帧是根据RDD构建的。但是,我最近得知情况并非如此,Difference between DataFrame, Dataset, and RDD in Spark很好地解释了事实并非如此。
那么将RDD转换为DataFrame并再次返回的开销是多少?是微不足道的还是重要的?
在我的应用程序中,我通过将文本文件读入RDD并随后使用返回Row()
对象的map函数自定义编码每一行来创建DataFrame。我不应该这样做吗?有没有更有效的方法?
答案 0 :(得分:1)
RDD在Spark中起着双重作用。首先是内部数据结构,用于跟踪阶段之间的变化以管理故障,其次是直到Spark 1.3成为与用户交互的主要界面。因此,在Spark 1.3之后,数据帧构成了提供比RDD更丰富的功能的主界面。
使用df.rdd
将一个Dataframe转换为RDD时,没有太大的开销,因为它们已经对RDD的实例进行了初始化,因此返回对该RDD的引用应该没有任何额外的开销。另一方面,从RDD生成数据帧需要付出额外的努力。通过调用rdd.toDF()
和使用spark.createDataFrame(rdd, schema)
调用2nd,有两种方法可以将RDD转换为数据帧。尽管模式验证和执行计划会产生额外的开销(尽管您可以检查toDF()
代码here了解更多信息)。当然,这与通过使用spark.read.text(...)
初始化数据而产生的开销相同,但少了一步,即从RDD转换为数据帧。
这是我直接使用数据框而不是使用两个不同的Spark接口的第一个原因。
第二个原因是,在使用RDD接口时,您缺少数据帧和数据集提供的与Spark优化器(催化剂)和内存管理(钨)相关的一些重要性能功能。
最后,仅当我需要数据帧中缺少的某些功能(例如键值对,zipWithIndex函数等)时,才使用RDDs接口。但是即使那样,您也可以通过df.rdd
访问这些功能,而这些功能已经是不昂贵的了提到。对于您的情况,我认为直接使用数据框并使用该数据框的map函数来确保Spark利用钨的使用来确保有效的内存管理会更快。