大数据学习之路85-spark2.0中的DataSet和DataFrame简介

DataSet是spark2.0提出来的新东西,我们来玩一下:

这次我们就不用SparkContext了,所以我们也不需要SparkConf了。

DataSet使用的是SparkSession.SparkSession其实是一个单例。

我们可以通过同样的方式创建schema,可是没有了SparkContext我们怎么创建RDD读取文件呢?我们可以通过SparkSession得到SparkContext,这样就好操作了。通过这个我们就可以看出来,SparkSession是对SparkContext的包装,SparkSession中持有SparkContext的引用。

在SparkSession中就不是创建表了,而是创建视图,

什么是视图呢?就是一个虚表,可以简化复杂的查询。

什么是DataFrame?就是将RDD与schema关联起来。我们查看一下DataFrame的源码可以发现:

大数据学习之路85-spark2.0中的DataSet和DataFrame简介_第1张图片

DataFrame其实是DataSet。这个其实是Spark1.6之后新出现的,在1.6之前这里应该是RDD。而DateSet号称要比RDD快100倍,这是为什么呢?

其实DataSet是一个优化之后的RDD。他的底层调用的还是RDD。只不过在执行之前,他有一个执行计划,优化器,他会对RDD进行优化然后再执行。

DateSet比RDD的好处就是,他里面的数据类型都是强类型。而以前我们RDD里面默认装的都是String类型。没有具体指定是什么类型。如果用之前的我们切分完数据之后如果想和Int类型进行比较的话还需要使用toInt等操作进行转换。

但是以后我们的DateSet就是强类型的,我们可以进行指定。

并且一旦指定是什么类型的我们就可以用lambda表达式的方式对DataSet进行处理。

一个DataFrame也是一个DateSet,他在DataSet中是以被命名的列的形式组织的。也就是说在spark中DataFrame其实是DataSet中装的row他在概念上和我们关系型数据库中的表是类似的。我们之所以可以进行优化,是因为一旦我们知道了有哪些列,我们就可以只加载我们需要的列,而不用全部加载。

DataSet是在RDD基础之上进行优化过的分布式数据集,里面的数据是强类型的,每一个字段都会有一个类型和名字。

通过DataSet可以创建DataFrame,在spark2.0,DataSet里面装的Row即DataSet[Row]。

接下来我们就来感受一下DataSet,我们使用spark2.x的方式来写个WordCount:

大数据学习之路85-spark2.0中的DataSet和DataFrame简介_第2张图片

我们使用SparkSession读取数据之后,也可以使用collect来查看,这样就和RDD没什么区别了,运行之后的结果为:

我们最好使用show方法:

大数据学习之路85-spark2.0中的DataSet和DataFrame简介_第3张图片

接下来我们先切分:

大数据学习之路85-spark2.0中的DataSet和DataFrame简介_第4张图片

这样就会报错:

这个错误告诉我们,如果我们想直接调用DataSet上面的算子还不行。我们还需要导入session对象中的隐式转换。

导入之后的运行结果:

大数据学习之路85-spark2.0中的DataSet和DataFrame简介_第5张图片

写到这一步我们就有两种选择,一种是写sql,另一种就是写DSL.

我们接下来先写DSL:

我们在语句中写的$意思是告诉他这是一列

为了可以使用agg中的聚合函数,我们还需要导入spark sql中的函数

代码如下:

package com.test.SparkSQL

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

object DataSetWordCount {
  def main(args: Array[String]): Unit = {
    //创建一个sparkSession
    val session: SparkSession = SparkSession.builder()
      .appName("DataSetWordCount")
      .master("local[*]")
      .getOrCreate()
    import session.implicits._
    val lines: Dataset[String] = session.read.textFile("D:/a/word.txt")
    val words: Dataset[String] = lines.flatMap(_.split(" "))
    import org.apache.spark.sql.functions._
    val result: Dataset[Row] = words.groupBy($"value" as "word")
      .agg(count("*") as "counts")
      .sort($"counts" desc)
    result.show()
  }
}

成功截图:

大数据学习之路85-spark2.0中的DataSet和DataFrame简介_第6张图片

或者我们也可以这样实现:

大数据学习之路85-spark2.0中的DataSet和DataFrame简介_第7张图片

成功截图:

大数据学习之路85-spark2.0中的DataSet和DataFrame简介_第8张图片

接着我们通过sql的方式来写WordCount

大数据学习之路85-spark2.0中的DataSet和DataFrame简介_第9张图片

withColumnRenamed是从RDD得到DataFrame的一种手段

代码如下:

package com.test.SparkSQL

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

object sqlWordCount {
  def main(args: Array[String]): Unit = {
    val session: SparkSession = SparkSession.builder()
      .appName("sqlWordCount")
      .master("local[*]")
      .getOrCreate()
    //指定读取数据的位置
    val lines: Dataset[String] = session.read.textFile("D:/a/word.txt")
    //导入sparksession中的隐式转换
    import session.implicits._
    val words: Dataset[String] = lines.flatMap(_.split(" "))
    val df: DataFrame = words.withColumnRenamed("value","word")
    //先创建视图,再执行sql
    df.createTempView("v_wc")
    val result: DataFrame = session.sql("select word,count(*) counts from v_wc group by word order by counts desc")
    result.show()

  }
}

运行结果如下:

大数据学习之路85-spark2.0中的DataSet和DataFrame简介_第10张图片

我们除了使用

 

这种方式,还可以使用上面提到的

session.read.format("text").load("D:/a/word.txt")

这种方式接下来的做法可以这样:

val words: Dataset[String] = lines.flatMap(_.getAs[String]("value").split(" "))

这种方式直接拿到的是DataFrame,DataFrame是什么东西?

通过这个我们可以看到,DataFrame就是DataSet中装的Row

所以就意味着我们拿出来的是一个row,而row中有可能有多个字段。我们可以将我们想要的字段拿出来,并转换成对应的类型。

DSL方式:

object sqlWordCount {
  def main(args: Array[String]): Unit = {
    val session: SparkSession = SparkSession.builder()
      .appName("sqlWordCount")
      .master("local[*]")
      .getOrCreate()
    //指定读取数据的位置
    //val lines: Dataset[String] = session.read.textFile("D:/a/word.txt")
    val lines: DataFrame = session.read.format("text").load("D:/a/word.txt")
    //导入sparksession中的隐式转换
    import session.implicits._
    val words: Dataset[String] = lines.flatMap(_.getAs[String]("value").split(" "))
//    val df: DataFrame = words.withColumnRenamed("value","word")
//    //先创建视图,再执行sql
//    df.createTempView("v_wc")
//    val result: DataFrame = session.sql("select word,count(*) counts from v_wc group by word order by counts desc")
//    result.show()

    //DSL方式
    import org.apache.spark.sql.functions._
    val result: Dataset[Row] = words.groupBy($"value").agg(count("*") as "counts").sort($"counts" desc)
    result.show()
    //val df = words.toDF()


  }
}

SQL方式:

 val df = words.toDF()
    df.createTempView("v_wc")
    val result: DataFrame = 
session.sql("select value word,count(*) counts from v_wc group by word order by counts desc")
    result.show()

我们也可以将执行的结果写入数据库:

大数据学习之路85-spark2.0中的DataSet和DataFrame简介_第11张图片

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