将 RDD 转换为 DataFrame 并再次转换回来的开销是多少?
Posted
技术标签:
【中文标题】将 RDD 转换为 DataFrame 并再次转换回来的开销是多少?【英文标题】:What's the overhead of converting an RDD to a DataFrame and back again? 【发布时间】:2019-04-27 21:48:25 【问题描述】:我假设 Spark 数据帧是从 RDD 构建的。但是,我最近了解到情况并非如此,Difference between DataFrame, Dataset, and RDD in Spark 很好地解释了它们不是。
那么将 RDD 转换为 DataFrame 并再转换回来的开销是多少?是微不足道还是重要?
在我的应用程序中,我通过将文本文件读入 RDD,然后使用返回 Row()
对象的 map 函数对每一行进行自定义编码来创建 DataFrame。我不应该这样做吗?有没有更有效的方法?
【问题讨论】:
好吧,您可以使用SparkSession.read.text("file")
,但仍需要将每一行解析为类型化列。
@cricket_007 是的,我可以这样做,但是使用它还是采用 RDD 方法更有效?
我认为这取决于输入格式。例如,json、avro、parquet 等具有明确定义的模式和类型...... Xml 或 csv 只是作为字符串读取,并且需要一些解析和转换为适当的数据类型才能使 Dataset 对象正常工作。就个人而言,我更喜欢从 Row 对象开始,然后在需要时构建 Dataset 模式,但我想不出你会回到 RDD 的情况
我们的输出格式是管道分隔的文本文件。
那么最好使用spark.read.option("delimiter", "|").csv("file")
作为DataFrame。
【参考方案1】:
RDD 在 Spark 中具有双重作用。首先是用于跟踪阶段之间更改以管理故障的内部数据结构,其次是直到 Spark 1.3 成为与用户交互的主要界面。因此,在 Spark 1.3 之后,Dataframe 构成了主界面,提供了比 RDD 更丰富的功能。
使用df.rdd
将一个 Dataframe 转换为 RDD 时没有显着的开销,因为它们已经初始化了 RDD 的实例,因此返回对该 RDD 的引用不应该有任何额外的成本。另一方面,从 RDD 生成数据帧需要一些额外的工作。有两种方法可以将 RDD 转换为数据帧,第一种是调用 rdd.toDF()
,第二种是调用spark.createDataFrame(rdd, schema)
。两种方法都将懒惰地评估,尽管关于模式验证和执行计划会有额外的开销(你可以检查toDF()
代码@ 987654321@了解更多详情)。当然,这与您使用spark.read.text(...)
初始化数据所产生的开销相同,但只需少一步,即从 RDD 到数据帧的转换。
这是我直接使用 Dataframes 而不是使用两个不同的 Spark 接口的第一个原因。
第二个原因是,在使用 RDD 接口时,您缺少一些重要的性能特性,这些特性是数据帧和数据集提供的与 Spark 优化器(催化剂)和内存管理(钨)相关的。
最后,只有当我需要一些数据帧中缺少的功能(例如键值对、zipWithIndex 函数等)时,我才会使用 RDD 接口。但即便如此,您也可以通过df.rdd
访问这些功能,正如已经提到的那样,这是无成本的。至于您的情况,我相信直接使用数据帧并使用该数据帧的 map 函数来确保 Spark 利用 tungsten 的使用来确保有效的内存管理会更快。
【讨论】:
“将一个 Dataframe 转换为 RDD 时没有显着的开销”。 ***.com/a/37090151/215945 暗示有一些(非平凡的)开销。这个答案似乎暗示它不仅仅是返回对底层 RDD 的引用。以上是关于将 RDD 转换为 DataFrame 并再次转换回来的开销是多少?的主要内容,如果未能解决你的问题,请参考以下文章