详解RDD、DataFrame、Dataset

转载:https://www.cnblogs.com/starwater/p/6841807.html

在Spark中,有三个针对数据的抽象结构:RDD、FataFrame、Dataset。


1 共同点

RDD、FataFrame、Dataset有以下共同点:

  1. RDD、FataFrame、Dataset都是分布式的弹性数据集,是对处理的数据的一种抽象。
  2. 都有 惰性机制,在 转化操作 时,不会立即执行,只有在遇到 行动操作 时才会开始计算。
  3. 都会根据Spark内存情况自动缓存运算,即使数据量很大也不用担心内存溢出问题。
  4. 都有partition分区的概念。
  5. 有许多共同的函数,例如filter、map等。

另外,DataFrame和Dataset都可以使用模式匹配获取各个字段的值和类型。


2 不同点

RDD

  1. RDD一般和Spark mlib一起使用。
  2. RDD不支持SparkSQL操作。

DataFrame

  1. DataFrame每一行的类型固定为Row,只有通过解析才能获取各个字段的值,例如:
peopleDF.foreach(
      line => {
        val name = line.getAs[String]("name")
        val age = line.getAs[Int]("age")
      }
    )

在DataFrame中,没法直接访问每一列的值。

  1. DataFrame与Dataset都支持SparkSQL的操作,比如select,groupby之类,还能注册临时表/视窗,进行sql语句操作:
dataDF.createOrReplaceTempView("tmp")
spark.sql("select ROW, DATE from tmp where DATE is not null order by DATE").show(100, false)
  1. DataFrame与Dataset支持一些特别方便的保存方式,比如保存成csv。

Dataset

  1. DataFrame可以理解为Dataset[Row],每一行的类型都是Row,不解析,无法直接知道每一行有哪些字段,需要通过getAs来处理。而Dataset中,每一行是什么类型是不一定的,在自定义了case class之后,可以很方便的获取每一行的信息:
case class Person(name:String, age: Int) extends Serializable
var personDS: Dataset[Person] = rdd.map(line => Person(line._1, line._2)).toDS

3 相互转换

RDD、DataFrame、Dataset三者互相转化如下。

DataFrame、Dataset转RDD

val rdd1 = testDF.rdd
val rdd2 = testDS.rdd

RDD转DataFrame

import ss.implicits._
val testDF = rdd.map(line => (line._1, line._2)).toDF("name", "age")

一般使用 元组 把一行的数据写在一起,然后在toDF中指定字段名。

RDD转Dataset

import ss.implicits._
case class Person(name:String, age: Int) extends Serializable
var personDS = rdd.map(line => Person(line._1, line._2)).toDS

可以注意到,定义每一行的类型(case class)时,已经给出了字段名和类型,后面只要往case class里面添加新的列名称和类型就可以了。

Dataset转DataFrame

import ss.implicits._
val testDF = testDS.toDF

DataFrame转Dataset

import ss.implicits._
case class Person(name:String, age: Int) extends Serializable
var personDS = testDF.as[Person]

这种方法就是在给出每一列的类型后,使用as方法,转成Dataset,这在数据类型是DataFrame又需要针对各个字段处理时极为方便。

你可能感兴趣的:(大数据)