SparkSql學(xué)習(xí)一

1 簡(jiǎn)介

SparkSql 可以從各種結(jié)構(gòu)化數(shù)據(jù)源讀取數(shù)據(jù)(JSON Hive Parquet等)中讀取數(shù)據(jù)贪绘。而且SparkSql還可以通過JDBC去讀去數(shù)據(jù)稠歉。

操作Spark SQL的方式有兩種:SQL API, Dataset API

2 SQL

SparkSql的用途之一就是執(zhí)行SQL查詢嚎杨。Spark sql 可以用來從已安裝的Hive里面讀取數(shù)據(jù)蹬耘。當(dāng)執(zhí)行SQL語句時(shí)返回的結(jié)果就是DataSet/DataFrame造烁。DataFrames can be constructed from a wide array of sources such as: structured data files, tables in Hive, external databases, or existing RDDs灰羽。根據(jù)官方英文我們可以知道DataFrames可以由結(jié)構(gòu)化文件(json),Hive 數(shù)據(jù)表渣刷,外在數(shù)據(jù)庫(kù)如mysql,oracle, 再或者已存在的RDD數(shù)據(jù)集構(gòu)造鹦肿。

3 使用方法

目前有兩套方式實(shí)現(xiàn)Spark Sql,其中一套就是老的辅柴,使用的是HiveContext以及 SchemaRDD 箩溃。 SchemaRDD 是一種特殊的RDD: SchemaRDD 是存放Row的RDD瞭吃,每個(gè)ROW對(duì)象代表一行記錄。這個(gè)很類似我們?cè)袛?shù)據(jù)庫(kù)的Schema涣旨。就像是表的結(jié)構(gòu)歪架。在后面的Spark版本SchemaRDD被DataFrame取代了。

3.1 數(shù)據(jù)準(zhǔn)備

這里我們先準(zhǔn)備一份json文件开泽,里面的數(shù)據(jù)很簡(jiǎn)單,命名為demo.json穆律,其文件內(nèi)容如下:

{"user":{"name":"Kason","location":"Beijing"},"text":"這個(gè)世界就是這樣"}
{"user":{"name":"Lucy","location":"Nanjing"},"text":"我也覺得樓上說得對(duì)"}

3.2 舊的API實(shí)現(xiàn):

package com.scala.action.spark_sql

import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.{SparkConf, SparkContext}

/**
  * Created by kason_zhang on 4/14/2017.
  */
object SparkSqlDemo extends App{

  val conf = new SparkConf().setAppName("SparkSqlDemo").setMaster("local[2]")
  val sc = new SparkContext(conf)
  val hiveCtx = new HiveContext(sc)
  val tweets = hiveCtx.jsonFile("D:\\work\\cloud\\demo.json")
  //注冊(cè)輸入的SchemaRDD
  tweets.registerTempTable("demo")
  //根據(jù)json文件選出名字與text
  val re = hiveCtx.sql("select user.name,text from demo")

  println(re.collect().foreach(println))

}

其輸出結(jié)果如下:

17/04/14 17:31:35 INFO CodeGenerator: Code generated in 14.157012 ms
[Kason,這個(gè)世界就是這樣]
[Lucy,我也覺得樓上說得對(duì)]

上面的流程很簡(jiǎn)單:就是構(gòu)造HiveContext,然后通過registerTempTable方法注冊(cè)SchemaRDD(你可以理解為注冊(cè)為數(shù)據(jù)庫(kù)表)峦耘,之后就可以執(zhí)行相關(guān)sql語句了,可以看到老方法還是很簡(jiǎn)單的辅髓。

3.3 DataFrame API實(shí)現(xiàn)

分為如下幾部

  • 創(chuàng)建SparkSession
  • 創(chuàng)建DataFrame
  • 注冊(cè)數(shù)據(jù)表DataFrame執(zhí)行數(shù)據(jù)表操作
    代碼code如下所示:
//創(chuàng)建SparkSession
  val spark_session = SparkSession.builder()
    .appName("Spark SQL basic")
    .config("spark.some.config.option","some-value")
    .getOrCreate()
  //讀取數(shù)據(jù)集
  val dataFrame = spark_session.read.json("D:\\work\\cloud\\demo.json")
  //展示數(shù)據(jù)表信息
  dataFrame.show()
  //把dataFrame注冊(cè)成為global temporary 視圖泣崩。
  dataFrame.createGlobalTempView("test")
  //執(zhí)行sql查詢
  spark_session.sql("select user.name,text from global_temp.test").show()

輸出的結(jié)果是:

spark_sql.png

dataFrame可以注冊(cè)成temporary view一種臨時(shí)性view,他是回話級(jí)別的洛口,基本上回話結(jié)束他生命周期也就結(jié)束了矫付。global temporary view與Spark Application的生命周期一致。

3.4 使用RDD

SparkSQL 支持兩種不同的方法轉(zhuǎn)換RDD為Dataset第焰。

  • 第一種方法
    通過反射推斷schema买优。當(dāng)我們已經(jīng)知道這個(gè)schema時(shí)此法很好用
    Scala接口支持自動(dòng)將case class的RDD轉(zhuǎn)化成DataFrame。case class定義了表結(jié)構(gòu)挺举,case class的參數(shù)會(huì)被反射成表結(jié)構(gòu)的列名杀赢。case class可以包括一些復(fù)雜類型如Seqs或者ArrayS。這種RDD可以隱含的轉(zhuǎn)成DataFrame然后注冊(cè)成數(shù)據(jù)表湘纵,即可執(zhí)行sql語句脂崔。
private def infer_schema_use_reflection(sparkSession: SparkSession): Unit ={

    //文件內(nèi)容這樣:
    /**
      * kason,12
      * lili,25
      * sime,30
      */
    //通過文件創(chuàng)建Person對(duì)象的RDD,并轉(zhuǎn)成DataFrame
    import sparkSession.implicits._
    val peopleDataFrame: DataFrame = sparkSession.sparkContext.textFile("D:\\data\\people.txt")
      .map(str => str.split(","))
      .map(attrs => Person(attrs(0),attrs(1).toInt))
      .toDF()
    peopleDataFrame.show()

    //注冊(cè)為臨時(shí)表
    peopleDataFrame.createOrReplaceTempView("people")
    //執(zhí)行sql查詢
    val selectRe: DataFrame = sparkSession.sql("select * from people where age > 10 and age < 30")
    //展示結(jié)果
    selectRe.show()
selectRe.map(row_people => "Name: " + row_people(0)).show()
    selectRe.map(row_people => "Age: " + row_people.getAs[Int]("age")).show()
  }
  • 第二種方法
    通過可編程接口梧喷,此方法比較冗余砌左,但是它允許你構(gòu)造Dataset即使你不知到列以及他的類型。
    此方法適用于不能提前預(yù)知case class铺敌。步驟:
    1绊困,根據(jù)軟式的RDD創(chuàng)建每行的RDD
    2,創(chuàng)建匹配Row RDD的結(jié)構(gòu)schem
    3适刀,通過createDataFrame方法應(yīng)用Row RDDde schema
    代碼如下:
private def Programmatically_specify_schema(sparkSession: SparkSession): Unit ={

    //Create RDD
    val peopleRDD = sparkSession.sparkContext.textFile("D:\\data\\people.txt")
    //The Schema is encoded in a string
    val schemaString = "name age"
    //Generate the real Schema based on the string of schema
    val fields = schemaString.split(" ")
      .map(fieldName => StructField(fieldName,StringType,nullable = true))
    val schema = StructType(fields)

    //將原始的RDD轉(zhuǎn)化成ROW RDD
    val rowRdd = peopleRDD.map(str => str.split(","))
      .map(attrs => Row(attrs(0),attrs(1).trim))

    //Apply schema to the ROW RDD
    val peopleDataFrame = sparkSession.createDataFrame(rowRdd,schema)

    //創(chuàng)建臨時(shí)表
    peopleDataFrame.createOrReplaceTempView("people")
    sparkSession.sql("select age from people").show()



  }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市煤蹭,隨后出現(xiàn)的幾起案子笔喉,更是在濱河造成了極大的恐慌取视,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件常挚,死亡現(xiàn)場(chǎng)離奇詭異作谭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)奄毡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門折欠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吼过,你說我怎么就攤上這事锐秦。” “怎么了盗忱?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵酱床,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我趟佃,道長(zhǎng)扇谣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任闲昭,我火速辦了婚禮罐寨,結(jié)果婚禮上序矩,老公的妹妹穿的比我還像新娘。我一直安慰自己贮泞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布囊蓝。 她就那樣靜靜地躺著聚霜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蝎宇。 梳的紋絲不亂的頭發(fā)上祷安,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音凉唐,去河邊找鬼。 笑死台囱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的簿训。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼膘侮,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼喻喳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起表伦,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤蹦哼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后纲熏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锄俄,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年鱼填,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了苹丸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赘理,死狀恐怖扇单,靈堂內(nèi)的尸體忽然破棺而出商模,到底是詐尸還是另有隱情阻桅,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站扮碧,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏慎王。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一蜀漆、第九天 我趴在偏房一處隱蔽的房頂上張望咱旱。 院中可真熱鬧,春花似錦吐限、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至肌蜻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間轰豆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工酸休, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留祷杈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓宿刮,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親胡桃。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容