SparkSQL 之 DataFrame, DataSet, RDD 之间的转换及关系

RDD、DataFrame、DataSet 三者的关系

➢ Spark1.0 => RDD
➢ Spark1.3 => DataFrame
➢ Spark1.6 => Dataset

如果同样的数据都给到这三个数据结构,他们分别计算之后,都会给出相同的结果。不同是的他们的执行效率和执行方式。在后期的 Spark版本DataSet 有可能会逐步取代RDD和DataFrame 成为唯一的API 接口。

三者的共性

➢ RDD、DataFrame、DataSet 全都是 spark 平台下的分布式弹性数据集,为处理超大型数据提供便利;
➢ 三者都有惰性机制,在进行创建、转换,如map 方法时,不会立即执行,只有在遇到Action 如 foreach 时,三者才会开始遍历运算;
➢ 三者有许多共同的函数,如 filter,排序等;
➢ 在对DataFrame 和Dataset 进行操作许多操作都需要这个包:import spark.implicits._(在创建好 SparkSession 对象后尽量直接导入)
➢ 三者都会根据 Spark 的内存情况自动缓存运算,这样即使数据量很大,也不用担心会内存溢出
➢ 三者都有 partition 的概念
➢ DataFrame 和DataSet 均可使用模式匹配获取各个字段的值和类型





三者的区别

RDD
➢ RDD一般和 spark mllib 同时使用
➢ RDD不支持 sparksql 操作

DataFrame
➢ 与RDD和Dataset 不同,DataFrame 每一行的类型固定为Row,每一列的值没法直接访问,只有通过解析才能获取各个字段的值
➢ DataFrame 与DataSet 一般不与 spark mllib 同时使用
➢ DataFrame 与DataSet 均支持 SparkSQL 的操作,比如 select,groupby 之类,还能注册临时表/视窗,进行 sql 语句操作
➢ DataFrame 与DataSet 支持一些特别方便的保存方式,比如保存成 csv,可以带上表头,这样每一列的字段名一目了然



DataSet
➢ Dataset 和DataFrame 拥有完全相同的成员函数,区别只是每一行的数据类型不同。DataFrame 其实就是DataSet 的一个特例 typeDataFrame = Dataset[Row]
➢ DataFrame 也可以叫Dataset[Row],每一行的类型是Row,不解析,每一行究竟有哪些字段,各个字段又是什么类型都无从得知,只能用上面提到的 getAS 方法或者共性中的第七条提到的模式匹配拿出特定字段。而Dataset 中,每一行是什么类型是不一定的,在自定义了case class 之后可以很自由的获得每一行的信息

RDD、DataFrame、DataSet 三者的转换

DataFrame与DataSet转换

package sparkSQL.study

import org.apache.spark.SparkConf
import org.apache.spark.sql.{
   
   Dataset, SparkSession}

object DF_DS {
   
   

  def main(args: Array[String]): Unit = {
   
   

    val conf = new SparkConf().setAppName("DataFrame_DateSet...").setMaster("local[*]")
    val sparkSession = SparkSession.builder().config(conf).getOrCreate()
    import sparkSession.implicits._

    // TODO DataFrame <==> DataSet

    val rdd = sparkSession.sparkContext.makeRDD(List(("zahngsan", 18), ("lisi", 20)))
    val dataFrame = rdd.toDF("name", "age")
    dataFrame.show()

    val ds = dataFrame.as[UserDF_DS]
    ds.show()
    val dataFrame1 = ds.toDF()
    dataFrame1.show()

    sparkSession.stop()

  }
  case class UserDF_DS( name:String, age:Int)

}

DataFrame与RDD转换

package sparkSQL.study

import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession

object DF_RDD {
   
   

  def main(args: Array[String]): Unit = {
   
   

    val conf = new SparkConf().setAppName("DataFrame_RDD...").setMaster("local[*]")
    val sparkSession = SparkSession.builder().config(conf).getOrCreate()
    import sparkSession.implicits._

    // TODO DataFrame <==> RDD

    val rdd = sparkSession.sparkContext.makeRDD(List(("zahngsan", 18), ("lisi", 20)))
    val dataFrame = rdd.toDF("name", "age")
    dataFrame.show()
    val rdd1 = dataFrame.rdd
    rdd1.collect().foreach(println)

    sparkSession.stop()

  }

}

RDD与DataSet转换

package sparkSQL.study

import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession

object RDD_DS {
   
   

  def main(args: Array[String]): Unit = {
   
   

    val conf = new SparkConf().setAppName("DataSet_RDD...").setMaster("local[*]")
    val sparkSession = SparkSession.builder().config(conf).getOrCreate()
    import sparkSession.implicits._

    // TODO RDD <==> DataSet

    val rdd = sparkSession.sparkContext.makeRDD(List(("zahngsan", 18), ("lisi", 20)))
    val ds = rdd.map {
   
   
      case (name, age) => {
   
   
        UserRDD_DS(name, age)
      }
    }.toDS()
    ds.show()
    val rdd1 = ds.rdd
    rdd1.collect().foreach(println)

    sparkSession.stop()

  }
  case class UserRDD_DS(name:String, age:Int)
}


所需依赖:

<dependency>
	<groupId>org.apache.spark</groupId>
	<artifactId>spark-sql_2.12</artifactId>
	<version>3.0.1</version>
</dependency>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章