zoukankan      html  css  js  c++  java
  • Spark中RDD、DataFrame和DataSet的区别

    前言

    最近同事开始学习使用Spark,问我RDD、DataFrame和DataSet之间有什么区别,以及生产环境中的spark1.6将在不久后被移除,全部使用spark2+。于是今天我就借机整理了以下它们三者之间的异同。

    RDD、DataFrame和DataSet的定义

    在开始Spark RDD与DataFrame与Dataset之间的比较之前,先让我们看一下Spark中的RDD,DataFrame和Datasets的定义:

    • Spark RDD
      RDD代表弹性分布式数据集。它是记录的只读分区集合。 RDD是Spark的基本数据结构。它允许程序员以容错方式在大型集群上执行内存计算。
    • Spark Dataframe
      与RDD不同,数据组以列的形式组织起来,类似于关系数据库中的表。它是一个不可变的分布式数据集合。 Spark中的DataFrame允许开发人员将数据结构(类型)加到分布式数据集合上,从而实现更高级别的抽象。
    • Spark Dataset
      Apache Spark中的Dataset是DataFrame API的扩展,它提供了类型安全(type-safe),面向对象(object-oriented)的编程接口。 Dataset利用Catalyst optimizer可以让用户通过类似于sql的表达式对数据进行查询。

    RDD、DataFrame和DataSet的比较

    Spark版本
    • RDD – 自Spark 1.0起
    • DataFrames – 自Spark 1.3起
    • DataSet – 自Spark 1.6起
    数据表示形式
    • RDD
      RDD是分布在集群中许多机器上的数据元素的分布式集合。 RDD是一组表示数据的Java或Scala对象。
    • DataFrame
      DataFrame是命名列构成的分布式数据集合。 它在概念上类似于关系数据库中的表。
    • Dataset
      它是DataFrame API的扩展,提供RDD API的类型安全,面向对象的编程接口以及Catalyst查询优化器的性能优势和DataFrame API的堆外存储机制的功能。
    数据格式
    • RDD
      它可以轻松有效地处理结构化和非结构化的数据。 和Dataframe和DataSet一样,RDD不会推断出所获取的数据的结构类型,需要用户来指定它。
    • DataFrame
      仅适用于结构化和半结构化数据。 它的数据以命名列的形式组织起来。
    • DataSet
      它也可以有效地处理结构化和非结构化数据。 它表示行(row)的JVM对象或行对象集合形式的数据。 它通过编码器以表格形式(tabular forms)表示。
    编译时类型安全
    • RDD
      RDD提供了一种熟悉的面向对象编程风格,具有编译时类型安全性。
    • DataFrame
      如果您尝试访问表中不存在的列,则持编译错误。 它仅在运行时检测属性错误。
    • DataSet
      DataSet可以在编译时检查类型, 它提供编译时类型安全性。
      [TO-DO 什么是编译时的类型安全]
    序列化
    • RDD
      每当Spark需要在集群内分发数据或将数据写入磁盘时,它就会使用Java序列化。序列化单个Java和Scala对象的开销很昂贵,并且需要在节点之间发送数据和结构。

    • DataFrame
      Spark DataFrame可以将数据序列化为二进制格式的堆外存储(在内存中),然后直接在此堆内存上执行许多转换。无需使用java序列化来编码数据。它提供了一个Tungsten物理执行后端,来管理内存并动态生成字节码以进行表达式评估。

    • DataSet
      在序列化数据时,Spark中的数据集API具有编码器的概念,该编码器处理JVM对象与表格表示之间的转换。它使用spark内部Tungsten二进制格式存储表格表示。数据集允许对序列化数据执行操作并改善内存使用。它允许按需访问单个属性,而不会消灭整个对象。

    垃圾回收
    • RDD
      创建和销毁单个对象会导致垃圾回收。
    • DataFrame
      避免在为数据集中的每一行构造单个对象时引起的垃圾回收。
    • DataSet
      因为序列化是通过Tungsten进行的,它使用了off heap数据序列化,不需要垃圾回收器来摧毁对象
    效率/内存使用
    • RDD
      在java和scala对象上单独执行序列化时,效率会降低,这需要花费大量时间。
    • DataFrame
      使用off heap内存进行序列化可以减少开销。 它动态生成字节代码,以便可以对该序列化数据执行许多操作。 无需对小型操作进行反序列化。
    • DataSet
      它允许对序列化数据执行操作并改善内存使用。 因此,它可以允许按需访问单个属性,而无需反序列化整个对象。
    编程语言支持
    • RDD
      RDD提供Java,Scala,Python和R语言的API。 因此,此功能为开发人员提供了灵活性。
    • DataFrame
      DataFrame同样也提供Java,Scala,Python和R语言的API
    • DataSet
      Dataset 的一些API目前仅支持Scala和Java,对Python和R语言的API在陆续开发中
    聚合操作(Aggregation)
    • RDD
      RDD API执行简单的分组和聚合操作的速度较慢。
    • DataFrame
      DataFrame API非常易于使用。 探索性分析更快,在大型数据集上创建汇总统计数据。
    • DataSet
      在Dataset中,对大量数据集执行聚合操作的速度更快。

    结论

    • 当我们需要对数据集进行底层的转换和操作时, 可以选择使用RDD
    • 当我们需要高级抽象时,可以使用DataFrame和Dataset API。
    • 对于非结构化数据,例如媒体流或文本流,同样可以使用DataFrame和Dataset API。
    • 我们可以使用DataFrame和Dataset 中的高级的方法。 例如,filter, maps, aggregation, sum, SQL queries以及通过列访问数据等
      如果您不关心在按名称或列处理或访问数据属性时强加架构(例如列式格式)。
      另外,如果我们想要在编译时更高程度的类型安全性。

    RDD提供更底层功能, DataFrame和Dataset则允许创建一些自定义的结构,拥有高级的特定操作,节省空间并高速执行。

    为了确保我们的代码能够尽可能的利用Tungsten优化带来的好处,推荐使用Scala的 Dataset API(而不是RDD API)。

    Dataset即拥有DataFrame带来的relational transformation的便捷,也拥有RDD中的functional transformation的优势。

    参考资料
    apache-spark-rdd-vs-dataframe-vs-dataset

  • 相关阅读:
    DFC-3C和DFC-3B的区别和注意事项
    Bug搬运工-CSCux99539:Intermittent error message "Power supply 2 failed or shutdown"
    EVE上传Dynamips、IOL和QEMU镜像
    EVE扩大虚拟内存
    EVE磁盘扩容
    VMware安装EVE
    介绍Mobility Group
    Bug搬运工-CSCvi02106 :Cisco 2800, 3800, 1560 APs: when connected to a Cisco Switch CDP-4-DUPLEX_MISMATCH log is seen
    jquery.autocomplete在火狐下的BUG解决
    nodeJS中exports和mopdule.exports的区别
  • 原文地址:https://www.cnblogs.com/lestatzhang/p/10611320.html
Copyright © 2011-2022 走看看