Spark SQL讀寫方法

來源:互聯網
上載者:User

標籤:sql語句   spl   map   應用   包含   必須   password   條件   初始化   

一、DataFrame:有列名的RDD

首先,我們知道SparkSQL的目的是用sql語句去操作RDD,和Hive類似。SparkSQL的核心結構是DataFrame,如果我們知道RDD裡面的欄位,也知道裡面的資料類型,就好比關係型資料庫裡面的一張表。那麼我們就可以寫SQL,所以其實這兒我們是不能用物件導向的思維去編程的。我們最好的方式就是把抽象成為一張表,然後去用SQL語句去操作它。

DataFrame的儲存方式:它採用的儲存是類似於資料庫的表的形式進行儲存的。一個資料表有幾部分組成:1、資料,這個資料是一行一行進行儲存的,一條記錄就是一行,2、資料表的資料字典,包括表的名稱,表的欄位和欄位的類型等中繼資料資訊。那麼DataFrame也是按照行進行儲存的,這個類是Row,一行一行的進行資料存放區。一般情況下處理粒度是行粒度的,不需要對其行內資料進行操作。

二、SparkSQL的程式入口:

在Spark2.0之前,是有sqlContext和hiveContext的概念的,因為這兩個概念難以區分,Spark2.0之後統一稱為SparkSession,除此之外SparkSession還封裝了SparkConf和SparkContext。

值得注意的一點是:Hive有很多依賴包,所以這些依賴包沒有包含在預設的Spark包裡面。如果Hive依賴的包能在classpath找到,Spark將會自動載入它們。這些Hive依賴包必須複製到所有的工作節點上,因為它們為了能夠訪問儲存在Hive的資料,會調用Hive的序列化和還原序列化(SerDes)包。Hive的設定檔hive-site.xml、core-site.xml(security配置)和hdfs-site.xml(HDFS配置)是儲存在conf目錄下面。 
當使用Hive時,必須初始化一個支援Hive的SparkSession,使用者即使沒有部署一個Hive的環境仍然可以使用Hive。當沒有配置hive-site.xml時,Spark會自動在當前應用目錄建立metastore_db和建立由spark.sql.warehouse.dir配置的目錄,如果沒有配置,預設是當前應用目錄下的spark-warehouse目錄。 

注意:從Spark 2.0.0版本開始,hive-site.xml裡面的hive.metastore.warehouse.dir屬性已經被spark.sql.warehouse.dir替代,用於指定warehouse的預設資料路徑(必須有寫入權限)。

於是SparkSQL在與Hive有互動的情況下,需要指定支援Hive:

val conf = new SparkConf().setAppName(s"${this.getClass.getSimpleName}")val spark = SparkSession.builder().config(conf).config("spark.sql.warehouse.dir","hdfs://hadoop1:9000/user/hive/warehouse").enableHiveSupport().getOrCreate()

回到正題,程式入口:

1.6版本:

val conf=new SparkConf()conf.setAppName(s"${this.getClass.getSimpleName}").setMaster("local")val sc=new SparkContext(conf)val sqlContext = new SQLContext(sc)

2.0版本:

SparkSQL的程式入口縮減為一句

 val sparkSession=SparkSession.builder().appName(s"${this.getClass.getSimpleName}").master("local").getOrCreate()

兩個版本一個獲得sqlContext(或者hiveContext),一個獲得sparkSession。

三、算了,還是放在一起寫吧。。

case  class Person(var name:String,var age:Int)object Test {  def main(args: Array[String]): Unit = {    //1.6版本入口    val conf=new SparkConf()    conf.setAppName(s"${this.getClass.getSimpleName}").setMaster("local")    val sc=new SparkContext(conf)    val sqlContext = new SQLContext(sc)    //第一種建立DataFrame的方式:直接讀取列式儲存的格式,可以直接形成DataFrame(後續怎麼操作呢?)    val df: DataFrame = sqlContext.read.json("")
    //第二種建立DataFrame的方式:因為rdd沒有toDF()方法,需要進行隱式轉化,通過map後形成一個數組    import sqlContext.implicits._    val df: DataFrame = sc.textFile("C:\\Users\\wangyongxiang\\Desktop\\plan\\person.txt").map(_.split(",")).map(p => Person(p(0), p(1).trim.toInt)).toDF()
    //第二種方法的另一種形態,用sqlContext或者sparkSession的createDataFrame(),其實和toDF()方法是雷同的    val rdd: RDD[Person] = sc.textFile("C:\\Users\\wangyongxiang\\Desktop\\plan\\person.txt")      .map(_.split(",")).map(p => Person(p(0), p(1).trim.toInt))    val df: DataFrame = sqlContext.createDataFrame(rdd)
    //第三種建立DataFrame:產生一個RowRDD,然後給出構造的描述    val rdd=sc.textFile("C:\\Users\\wangyongxiang\\Desktop\\plan\\person.txt")    val rowRDD: RDD[Row] = rdd.map(_.split(",")).map(p=>Row(p(0),p(1).trim.toInt))    val schame=StructType(      StructField("name",StringType,true)::      StructField("age",IntegerType,true)::Nil    )    val df: DataFrame = sqlContext.createDataFrame(rowRDD,schame) 
    //後續代碼,可以建立臨時視圖作為查詢,與mysql互操作要建立臨時視圖才能做查詢
    //用hiveContext則直接在hive中建立表,然後將資料load到hive表中,可以直接進行條件查詢,無需建立臨時視圖,後面與hive整合會有說明    df.registerTempTable("person")    sqlContext.sql("select * from person where age>21").show()    //將處理後的資料用jdbc儲存到mysql資料庫中成為一張表,注意這裡要使用user而不能使用username,因為系統也有一個username,會覆蓋你的使用者名稱    val properties=new Properties()    properties.put("user","root")    properties.put("password","root")    df.write.mode(SaveMode.Overwrite)jdbc("jdbc:mysql://localhost:3306/test","test",properties)  }}

四、load和save操作。

object saveAndLoadTest {  def main(args: Array[String]): Unit = {    val conf =new SparkConf().setAppName("").setMaster("local")    val sc=new SparkContext(conf)    val sqlContext=new SQLContext(sc)     //read,load:讀取    sqlContext.read.json("")//  sqlContext.read.jdbc("url","table",properties)    sqlContext.read.load("parquet路徑")    sqlContext.read.format("json").load("路徑")    val df: DataFrame = sqlContext.read.format("parquet").load("路徑")     //write,save儲存    df.write.parquet("路徑.parquet")    df.write.json("路徑.json")//  df.write.jdbc("url","table",properties)    df.write.format("parquet").save("路徑.parquet")    df.write.format(("json")).save("路徑.json")    //儲存模式可選擇覆蓋,追加等    df.write.mode(SaveMode.Overwrite).save("")  }}

個人理解是read和load都是讀取的作用,write和save都是儲存的作用,通過上述的代碼,我們可以完成檔案格式轉換的工作,將效率低的一些格式轉化成parquet這種sparksql原生支援的檔案類型

 

Spark SQL讀寫方法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.