史上最簡單的spark教程第十章-SparkSQL編程Java案例實踐(二)

Spark-SQL的Java實踐案例(二)

史上最簡單的spark教程
所有代碼示例地址:https://github.com/Mydreamandreality/sparkResearch

(提前聲明:文章由作者:張耀峯 結合自己生產中的使用經驗整理,最終形成簡單易懂的文章,寫作不易,轉載請註明)
(文章參考:Elasticsearch權威指南,Spark快速大數據分析文檔,Elasticsearch官方文檔,實際項目中的應用場景)
(幫到到您請點點關注,文章持續更新中!)
Git主頁 https://github.com/Mydreamandreality

在這裏我們繼續上一章節SparkSQL的案例啊,沒有看上一章節的兄弟萌 點擊這裏哈https://blog.csdn.net/youbitch1/article/details/88852644

在這裏插入圖片描述
[給盧姥爺上香]


  • 上一章節的最開始,我們說爲了實現sparkSQL的功能,spark提供了一種全新的RDD叫做
    DataFrame,但是我們的SparkSQL返回值一直是DataSet,可能有些兄弟就有點不理解了啊
  • Dataset其實是一個分佈式的數據收集器
  • DataFrame可以從廣泛的數據源中構成.比如:結構化的數據文件,Hive的table,外部數據庫和RDD
  • DataFrame在Scala,Java,Python和R中都支持,在Java中爲Dataset
  • 這就兄弟萌能理解爲啥返回DataSet了吧
  • 更具體的東西咱寫到後面再分析一波
    在這裏插入圖片描述

  • 上一章節的最後,我們以編程的方式運行sparkSQL查詢,把dataframe註冊成爲臨時表運行SQL語句(也可以稱爲臨時視圖)

  • 但是它有個很大的問題

    • 臨時表是當前使用的SQLContext中的臨時變量,在我們的的應用退出時這些臨時表就不再存在了
    • 說白了就是臨時視圖是session級別的,它會隨着session的消息而消失
  • 那如果我們想要一個臨時視圖在所有的session中互相傳遞使用,直到spark的應用終結,該咋辦

    • 這個時候我們只需要創建一個全局臨時視圖即可

全局臨時視圖

  • 全局臨時視圖存在於系統數據庫的global_temp
  • 全局臨時視圖的生命週期隨spark程序的運行消失
  • 在這裏插入圖片描述
  • 來吧讓我們用代碼說話,代碼案例:
        try {
            //創建全局臨時視圖
            dataset.createGlobalTempView("user");
            //全局臨時視圖綁定到系統保存的數據庫“global_temp”
            Dataset<Row> globalUser = sparkSession.sql("SELECT * FROM global_temp.user");
            sparkSession.newSession().sql("SELECT * FROM global_temp.user");
        } catch (AnalysisException e) {
            e.printStackTrace();
        }
  • 代碼還是很簡單的
  • 首先創建我們的全局臨時視圖,使用createGlobalTempView函數創建(在上一章節中創建臨時視圖使用的函數是createOrReplaceTempView)
  • 其次我們說了,我們的全局臨時視圖綁定到我們的系統庫 global_temp中,所以在查詢的時候需要先指定我們的系統庫(系統庫無需關注,系統自帶的)
  • 最後呢,我們說過,全局臨時變量是跨會話的,所以你可以在新會話中執行我們的SQL語句
  • 在這裏插入圖片描述

創建DataSet

  • DataSet和RDD比較類似,不同的地方就是序列化的方式
  • RDD序列化是使用Java的serialization或者kryo實現序列化和反序列化的
  • DataSet是使用的encoder來實現對象的序列化和在網絡中的傳輸
  • encoder有個動態的特性,Spark在執行比如sorting之類的操作時無需再把字節反序列化成對象
  • 代碼示例:
        SparkSession sparkSession = SparkSession.builder().master("local")
                .appName("Java Spark SQL")
                .getOrCreate();
        Person person = new Person("spark",10);
        Encoder<Person> encoder = Encoders.bean(Person.class);
        Dataset<Person> dataset = sparkSession.createDataset(Collections.singletonList(person),encoder);
        dataset.show();
        //最終輸出 {name:spark;age:10}


        /*常見類型的編碼器*/
        Encoder<Integer> integerEncoder = Encoders.INT();
        Dataset<Integer> integerDataset = sparkSession.createDataset(Arrays.asList(1,2),integerEncoder);
        Dataset<Integer> result = integerDataset.map(new MapFunction<Integer, Integer>() {
            @Override
            public Integer call(Integer value) {
                return value+1;
            }
        },integerEncoder);
        result.collect();
        //最終輸出 [2,3]
        
        
         /*通過提供一個類,可以將數據流轉換爲數據集。基於名稱的映射*/
        String url = "/usr/local/text.json";
        Dataset<Person> personDataset = sparkSession.read().json(url).as(encoder);
        personDataset.show();
        //最終輸出 name:...  age:,,,,
  • 上面這個案例如何理解?
  • 靈魂畫手上線:
    *在這裏插入圖片描述
  • 這樣就很好理解了,下面兩個案例同理,只是數據類型爲基礎類型
    在這裏插入圖片描述

這章的最後在這裏總結一下 RDD和dataframe,DataSet的區別

  • RDD
  • 彈性分佈式數據集.是Spark對數據進行的一種抽象,可以理解爲Spark對數據的一種組織方式.更簡單些說.RDD就是一種數據結構.裏面包含了數據和操作數據的方法
  • 關鍵字:
    • 彈性,分佈式,數據集

  • DataFrame
  • 理解了RDD.DataFrame就容易理解些
  • RDD是一個數據集,DataFrame在RDD的基礎上增加了Schema(描述數據的信息,可以認爲是元數據,DataFrame曾經就叫做schemaRDD)
  • 做個對比,如果左邊的數據是RDD,那麼右邊的就是dataframe
  • 在這裏插入圖片描述
  • DataFrame比RDD多了一個表頭信息(Schema),像一張表,DataFrame還配套了新的操作數據的方法,DataFrameAPI 比如df.select()和SQL(select id, name from xx_table where …))等等
  • 正因爲有了這層抽象,我們開發才能很爽啊,處理數據就變得很簡單了
  • 不僅如此.通過DataFrame API或SQL處理數據.會自動經過Spark的優化器(Catalyst)的優化.即使你寫的程序或SQL不高效,也可以運行的很快
  • 注意:DataFrame是用來處理結構化數據的

  • DataSet
  • 對於RDD而言,DataSet做了強類型支持,在RDD的每一行都做了數據類型約束
  • RDD轉換DataFrame後不可逆,但RDD轉換Dataset是可逆的
  • 下面這就是DataSet的數據
    在這裏插入圖片描述
這章就先到這裏啦,這章我們知道了創建DataSet的方式還有RDD和dataframe,dataset的區別
下一章節寫RDD和DataSet的轉換操作吧

在這裏插入圖片描述

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