Spark SQL編程指南(Python)

來源:互聯網
上載者:User

標籤:

前言 Spark SQL允許我們在Spark環境中使用SQL或者Hive SQL執行關係型查詢。它的核心是一個特殊類型的Spark RDD:SchemaRDD。 SchemaRDD類似於傳統關係型資料庫的一張表,由兩部分組成: Rows:資料行對象Schema:資料行模式:列名、列資料類型、列可否為空白等 Schema可以通過四種方式被建立: (1)Existing RDD(2)Parquet File(3)JSON Dataset(4)By running Hive SQL 考慮到Parquet File尚未在平台開始使用,因此暫時僅討論其它三項。 注意: Spark SQL is currently an alpha componentSQLContext(HiveContext) Spark SQL的進入點為SQLContext,SQLContext的初始化依賴於SparkContext,程式碼範例如下:  SQLContext目前僅僅使用一個簡單的SQL解析器,功能有限,而且目前很多的資料倉儲是建立在Hive之上的,因此Spark為我們提供了另一個選擇:HiveContext。 HiveContext使用相對比較完善的HiveQL解析器,可以使用HiveUDF,可以訪問現有Hive資料倉儲中的資料,且適配SQLContext的所有資料來源,推薦使用。 HiveContext初始化過程相似,如下:   資料來源 Spark SQL(SchemaRDD)的資料來源可以簡單理解為就是普通的Spark RDD,所有可以應用於Spark RDD的操作均可以應用於SchemaRDD;此外,SchemaRDD還可以“註冊”為一張暫存資料表,然後通過SQL(Hive SQL)分析其中的資料(實際就是Spark RDD關聯的資料)。  SchemaRDD SchemaRDD的資料來源實際就是Spark RDD,但是Spark RDD與SchemaRDD還是有區別的,Spark RDD相對於SchemaRDD而言缺失“Schema”,因此Spark提供兩種方式完成Spark RDD到SchemaRDD的轉換,實際就是為Spark RDD應用“Schema”。 (1)使用反射推斷Schema 如果一個Spark RDD的資料類型為Row,則Spark可以通過反射推斷出該Spark RDD的Schema,並將其轉換為一個SchemaRDD。 Spark使用反射推斷某個Spark RDD的Schema時,僅僅使用這個Spark RDD的第一條資料(Row),因此必須保證這條資料的完整性。 Row的構建過程需要一個索引值對列表, Row(id = 1, name = "a", age = 28) 這個索引值對列表已經明確定義出資料行的列名、列值,推斷僅作用於列類型。 程式碼範例  處理邏輯可以分為以下幾步: a. 建立一個字串列表datas,用於類比資料源;b. 對datas執行“parallelize”操作,將其轉換為Spark RDD source,資料類型為字串;c. 將Spark RDD source中的每一條資料進行切片(split)後轉換為Spark RDD rows,資料類型為Row; 至此Spark RDD rows已經具備轉換為SchemaRDD的條件:它的資料類型為Row。 d. 使用HiveContext推斷rows的Schema,將其轉換為SchemaRDD people; 通過people.printSchema(),我們可以查看推斷Schema的結果:  e. 將SchemaRDD people註冊為一張暫存資料表“people”; f. 執行SQL查詢語句:select * from people where age > 28 and age < 30,並將查詢結果儲存至Spark RDD results,通過results.printSchema()的輸出結果:  可以看出Spark RDD results實際也是SchemaRDD,因此我們可以繼續將其註冊為一張暫存資料表; g. 將SchemaRDD results註冊為一張暫存資料表“people”,並執行SQL查詢語句:select name from people2,並將查詢結果儲存至Spark RDD results2,通過f我們可以知道results2實際也是SchemaRDD,results2.printSchema()的輸出結果:  SchemaRDD results2的資料類型為Row,受到查詢語句(select name)的影響,其僅包含一列資料,列名為name。 h. SchemaRDD也可以執行所有Spark RDD的操作,這裡我們通過map將results2中的name值轉換為大寫形式,最終的輸出結果:  上述樣本說明以下三點: a. 我們可以將一個資料類型為Row的Spark RDD轉換為一個SchemaRDD; b. SchemaRDD可以註冊為一張暫存資料表執行SQL查詢語句,其查詢結果也是一個SchemaRDD; c. SchemaRDD可以執行所有Spark RDD的操作。 (2)通過編碼指定Schema 使用反射推斷Schema的方式要求我們必須能夠構建一個資料類型為Row的Spark RDD,然後再將其轉換為SchemaRDD;某些情況下我們可能需要更為靈活的方式控制SchemaRDD構建過程,這正是通過編碼指定Schema的意義所在。 通過編碼指定Schema分為三步: a. 構建一個資料類型為tuple或list的Spark RDD;b. 構建Schema,需要匹配a中的tuple或list;c.將b中的Schema應用於a中的Spark RDD。 程式碼範例  代碼處理邏輯正好對應著上述三步,最終的輸出結果:  其中需要注意id、age的資料類型被聲明為IntegerType,因此資料來源(字串)中的資料需要做強制類型轉換處理。  JSON Datasets Spark能夠自動推斷出Json資料集的“資料模式”(Schema),並將它載入為一個SchemaRDD執行個體。這種“自動”的行為是通過下述兩種方法實現的: jsonFile:從一個檔案目錄中載入資料,這個目錄中的檔案的每一行均為一個JSON字串(如果JSON字串“跨行”,則可能導致解析錯誤); jsonRDD:從一個已經存在的RDD中載入資料,這個RDD中的每一個元素均為一個JSON字串; 程式碼範例  可以得出以下兩點: a. 如果資料輸入是JSON字串的文字檔,我們可以直接使用jsonFile構建Spark RDD,實際就是SchemaRDD; b. 如果某個Spark RDD的資料類型是字串,且字串均是JSON格式的字串形式,則可以使用jsonRDD將其轉換為一個SchemaRDD。  Hive Tables Hive Tables已經是“表”,因此我們無需建立或轉換,直接使用SQL查詢即可。 官方程式碼範例   Hive UDF(Register Function) Spark SQL使用HiveContext時可以支援Hive UDF,這裡的UFD包含Hive本身內建的UDF,也包括我們自己擴充的UDF(實測Spark-1.2.0-cdh5.3.2版本下無法正常使用自己擴充的UDF(Permanent Function),已通過擴充源碼修複)。 這裡重點介紹Spark SQL的Register Function,也就是說可以動態建立函數用於SQL查詢,其實際作用類似於Hive UDF。 程式碼範例  代碼的處理邏輯與前大體類似,即首先通過編碼建立SchemaRDD people,然後將其註冊為一張表(注意這裡使用了另一種方式:HiveContext registerRDDAsTable),最後執行查詢語句並列印結果。 特別的是查詢語句中使用到了一個名為“myfunc”的自訂SQL函數,而這個函數並不是預先存在的(如Hive UDF),它是在我們應用的運行期間被動態建立並註冊的,註冊過程使用到了HiveContext registerFunction。 對於Python而言,自訂函數的建立過程實際可分為兩步: (1)定義Python Function;(2)將(1)中定義好的Python Function註冊為SQL函數,註冊時的命名可與Function的名稱不同。 也可以使用Lambda運算式將定義Function與註冊過程同時完成,如上述樣本。 我們自訂的SQL函數可以與Hive UDF共同使用,如下樣本:   其中func.iptolocationbysina是Hive UDF(Permanent Function),mychange是自訂SQL函數。 從上面的兩個樣本可以看出,自訂SQL函數遠比Hive UDF靈活。Hive UDF的建立過程比較複雜,需要使用Java語言完成編碼並部署為jar,且在使用函數之前需要以temporaty function或permanent function的形式存在,每一次Hive UDF的更新都需要重新編碼並更新jar;而自訂SQL函數是運行期間動態建立的,而使用Python編碼時Function的建立及更新非常簡便,推薦使用。  總結 Spark SQL為我們提供了強大的資料分析能力,主要體現在以下三個方面: (1)Spark RDD可以通過反射推斷Schema或編碼指定Schema的方式轉換為SchemaRDD,將SchemaRDD建立為“資料表”之後,允許我們以SQL語句的形式分析資料,節約大量編碼工作量;(2)Spark SQL允許我們在應用運行期間根據需求動態建立自訂SQL函數,擴充SQL的資料處理能力;(3)SchemaRDD可以執行所有Spark RDD的操作,如果SQL無法表述我們的計算邏輯時,我們可以通過Spark RDD豐富的API完成。            

Spark SQL編程指南(Python)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.