SparkSQL 簡單總結一下和一個WC案例

SparkSQL總結:

一、Spark SQL

是Spark用來處理結構化數據的一個模塊,它提供了一個編程抽象叫做DataFrame,並且作爲分佈式SQL查詢引擎的作用

二、什麼是DataFrames??

與RDD類似,DataFrames也是一個分佈式數據容器;然而DataFrame更像傳統數據庫的二維表格,除了數據以外,還記錄數據的結構信息,即schema;
同時與Hive類似,DataFrame也支持嵌套數據類型(struct,array,map).

三、創建dataframe的兩種方式:

通過數據源採集直接創建成DF格式(spark.read.json(Path))
通過StructType創建Schema,通過createDataFrame來創建DF
DataFrame與DataSet與RDD互相轉換
(1)DataFrame -> DataSet
val dataSet = dataFrame.as[Person]
(2)DataSet -> DataFrame
val dataFraem = dataSet.toDF()
(3)DataFrame -> RDD
val RDD = dataFrame.rdd

四、DataFrame兩種風格語法常用操作

1、DSL(領域特定語言)風格操作

2、SQL風格操作
DataFrame的一個強大之處就是我們可以將它看作是一個關係型數據表,然後可以通過在程序中使用spark.sql() 來執行SQL語句查詢,結果返回一個DataFrame:
spark.sql(“SQL語句”).show
如果想使用SQL風格的語法,需要將DataFrame註冊成表:
personDF.registerTempTable(“t_person”)

五、DataSet和DataFrame的區別

1、DataSet包含了DataFrame的功能,Spark2.0中兩者統一,DataFrame表示爲DataSet[Row],即DataSet的子集。
2、相比DataFrame,Dataset提供了編譯時類型檢查,對於分佈式程序來講,提交一次作業太費勁了(要編譯、打包、上傳、運行),
到提交到集羣運行時才發現錯誤,這會浪費大量的時間,這也是引入Dataset的一個重要原因。

3、DS狀態的RDD[Person]雖然以Person爲類型參數,但Spark框架本身不瞭解 Person類的內部結構。
而DataFrame卻提供了詳細的結構信息,使得Spark SQL可以清楚地知道該數據集中包含哪些列,每列的名稱和類型各是什麼,DataFrame多了數據的結構信息,
即schema。這樣看起來就像一張表了。
4、DataFrame通過引入schema和off-heap(不在堆裏面的內存,指的是除了不在堆的內存,使用操作系統上的內存),解決了RDD的缺點,
Spark通過schame就能夠讀懂數據, 因此在通信和IO時就只需要序列化和反序列化數據, 而結構的部分就可以省略了;通過off-heap引入,
可以快速的操作數據,避免大量的GC。但是卻丟了RDD的優點,DataFrame不是類型安全的, API也不是面向對象風格的

5、off-heap
DataFrame還引入了off-heap,意味着JVM堆以外的內存, 這些內存直接受操作系統管理(而不是JVM)。Spark能夠以二進制的形式序列化數據(不包
括結構)到off-heap中, 當要操作數據時, 就直接操作off-heap內存. 由於Spark理解schema, 所以知道該如何操作。

六、SparkSQL實現的WordCount

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

/**
 * @description ${DESCRIPTION}
 * @author YDAlex
 * @data 2019/11/20.
 * @version 1.0
 */
object wc {

  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder()
      .appName("wordCount")
      .master("local[*]")
      .getOrCreate()
    val words = spark.read
      .textFile("G:\\IntelliJ IDEA 2019.2.1\\Workspace\\sparkStreaming\\data\\wc.txt")
    import spark.implicits._
    val word: Dataset[String] = words.flatMap(_.split(" "))
    //SQL style
    word.createOrReplaceTempView("word")//創建臨時表
    /*SELECT value, COUNT(*) counts FROM word GROUP BY value ORDER BY counts DESC*/
    val result = spark.sql(
      """
        |select
        |value,
        |count(*) counts
        |from word
        |group by value
        |order by counts desc
        |""".stripMargin)
    result.show()

    //DSLStyle
    import org.apache.spark.sql.functions._
    word.groupBy($"value" as "word")
      .agg(count("*") as "counts")
      .orderBy($"counts" desc)
      .show()


    spark.close()
  }
}



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