Spark簡介 Introduction to Spark -...

Post on 06-Jul-2020

3 views 0 download

Transcript of Spark簡介 Introduction to Spark -...

巨量資料技術與應用Big Data Technology and Application

資訊管理學系陳士杰老師

Spark SQLFundamental Principles of Spark

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

2

大綱

Spark SQL簡介

建立DataFrame

保存DataFrame

DataFrame的常用操作

從RDD轉成DataFrame

使用Spark SQL讀寫資料庫

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

3

Spark SQL簡介

Spark SQL是Spark中用於結構化資料處理的元件

採用DataFrame資料模型

帶有Schema的RDD

可連結多種不同類型的資料來源

Hive, Avro, Parquet, JSON, JDBC, …

支援多種程式語言之撰寫

Scala, Java, Python, …

為何會有Spark SQL,一切需從Shark說起

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

4

從Shark說起

• 最早,由於許多資料分析師不熟悉Java,

而無法進行深入的MapReduce程式設

計。

• 為了讓他們能使用熟悉的SQL語法來操

作HDFS上的資料,進而推出了Hive。

• 然而,Hive最大的問題點是:其底層是

基於MapReduce,而MapRecuce的

Shuffle運作又是基於硬碟,因此導致其

運作性能低下。

• 後來,Spark推出基於記憶體運作的

Shark。Shark即Hive on Spark,其性

能比Hive高一個等級,且能與Hive相容。

Hive中SQL查詢的MapReduce作業轉化過程

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

5

• 為了與Hive相容,Shark的實作在HiveQL指令方面,重用了Hive中

HiveQL指令解析與最佳化等元件。因此,可大致視其為僅將實體執行

計畫從MapReduce作業替換成了Spark作業,透過Hive的HiveQL解析,

把HiveQL轉譯成Spark上的RDD操作。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

6

• Shark的設計導致了兩個問題:

• 一是指令執行最佳化仍完全依賴於Hive,不易增加新的最佳化策略,進

而限制了Shark性能提升的可能性;

• 二是因為Spark是執行緒等級並行,而MapReduce是行程等級並行,因

此,Spark在相容Hive的實作上存在執行緒安全問題,導致Shark不得不

使用另外一套獨立維護、且上了更新檔之Hive程式碼分支

• 行程(Process) vs. 執行緒(Thread) – 請參閱作業系統課程

• 因此,在2014年6月Spark宣佈不再開發Shark,全面轉向Spark SQL的

開發。從Spark1.0開始,Spark SQL成為了Spark生態系統的一員。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

7

Spark SQL設計

• Spark SQL在Hive相容層面僅依賴HiveQL解析、Hive中繼

資料。也就是說,從HiveQL被解析成抽象語法樹(AST)之

後,就全部由Spark SQL接管了。

• SparkSQL執行計畫生成和最佳化都由Catalyst(函數式關

係查詢最佳化框架)負責

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

8

Spark的運作核心為RDD 。有許多不同的RDD API

RDD API的局限性

沒有Schema

因為沒有Schema,所以使用者需自已最佳化程式

從不同的資料來源讀取資料非常困難

合併多個資料來源的資料也很困難

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

以下建立一個名為arrayrdd02的RDD,其值為[2, 3, 4, 5,

6];接著,用一個map函數將其轉換成另一個RDD,名

為Ardd02;最後,用函數檢視Ardd02的元素。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

10

• Spark SQL使用了SchemaRDD (Spark 1.3版本前對DataFrame的

稱呼,即:RDD + Schema,帶有Schema訊息的RDD),讓使用者

可以在SparkSQL中執行SQL語句,資料既可以來自RDD,也可以是

Hive、HDFS、Cassandra或JSON格式…等之外部資料來源

• RDD為Schema less的資料結構,只有值,沒有其它描述資訊,不易瞭

解值的意義,後續資料處理也較為複雜。

• Spark SQL目前支持Scala、Java、Python三種語言,支援SQL-92

規範

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

11

DataFrame與Dataset

Spark SQL是佈署在Spark RDD API與運算框架之上,有

兩層:

Catalyst最佳化引擎:根據資料的分佈與特點,用以最佳化SQL

指令

兩種編寫應用程式的方法:SQL與DataFrame/Dataset API

Spark SQL不僅僅是SQL…

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

12

使用SQL

如果使用者很熟悉SQL語法,則可使用SQL

使用DataFrame/Dataset

在Spark 1.3以前,被稱為SchemaRDD

SQL語法表達能力有限 (ex:無法迭帶)

可採用更通用的語言(Scala, Python)來表達使用者的查詢需求

使用DataFrame更快的捕獲錯誤

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

13

DataFrame

下方左側的RDD[Person]雖然以Person為物件參數,但Spark框

架本身不瞭解Person物件的內部結構

右側的DataFrame提供了詳細的結構資訊

Spark可以清楚得知該資料集中包含哪些欄、每欄的名稱和類型為何

Spark可獲得高計算效能,並支持SQL查詢

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

14

以Row物件為主的分散式資料集合

如同RDD,不可改變且具有容錯能力

處理結構化資料

自帶最佳化工具Catalyst,可自動最佳化程式

提供一套Data source API,可將不同資料來源的資料,轉換成

RDD[Row] => DataFrame

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

RDD、DataFrame、Dataset綜整

RDD

第一代Spark API

起源自Spark 0

彈性分散式資料集

不包含Schema

非結構性資料,後續

處理上不方便

DataFrame

第二代Spark API

起源自Spark 1.3

欄(Column)為主的分

散式資料集

包含Schema

結構性資料,後續處

理、計算或壓縮上較

RDD方便且有效率

Dataset

第三代Spark API

起源自Spark 1.6。Spark 2.0後整合

DataFrame成為Dataset的特例

Encoder的分散式資料集

序列化的結構性資料,已將資料編

碼轉換成二進制序列。

Spark自行發展一套編碼與反編碼的

規則。某些操作無需序列化,執行

效能更高於DataFrame

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

相同點:

RDD、DataFrame、Dataset全都是spark平臺下的彈性分散式

資料集,為處理超大型資料提供便利性

三者都有惰性機制,在進行建立、轉換,如map方法時,不會立

即執行,只有在遇到Action如foreach時,三者才會開始自頭至

尾加以運算

極端情況下,如果程式碼內有建立、轉換而沒有Action操作時,在

執行時會被直接跳過

三者都會根據spark的記憶體情況自動快取運算,這樣即使資料

量很大,也不用擔心會記憶體滿溢情況

三者都有partition的概念

三都有共同的函數,如filter等

無論使用哪種API (Dataframe或Dataset),內部最終計

算都在RDD上完成。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

建立DataFrame

在Spark 1.6之前,要將資料載入到Spark進行處理,需先

透過SparkContext將待處理資料轉換成RDD物件。

同樣的,要在Spark內進行DataFrame相關資料操作,就

要將資料轉換成DataFrame物件,而SQLContext和

HiveContext可以達成此需求。

SQLContext可以將資料轉換成DataFrame物件以進行SQL操作

HiveContext可以將資料轉換成DataFrame物件以進行HiveQL

的操作。

而在Spark的其它API也需要使用不同的Context,例如:

關於串流資料Streaming的處理,可以使用StreamingContext

將資料轉換成可進行Spark Streaming操作的物件。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

Spark2.0以後的版本,使用全新的SparkSession介面替

代過去的SQLContext及HiveContext介面來實現其對資

料載入、轉換、處理等功能,並實現SQLContext及

HiveContext所有功能

SparkSession支援從不同的資料來源載入資料,並把資料轉換成

DataFrame,同時也支援把DataFrame轉換成SQLContext自身

的表格,然後使用SQL指令來進行運算。

SparkSession亦提供HiveQL以及其他依賴於Hive的功能支援

未來有可能連StreamingContext也會被併入

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

與SparkContext相同,在Spark Shell或PySpark互動環

境時,已預設提供了一個SparkContext物件(名為sc)與

SparkSession物件(名為spark)。

當開發人員撰寫獨立程式時,就需要自行建立一個

SparkSession物件,指令如下所示:

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

接下來可以用spark.read這個SparkSession物件方法,

將不同類型的文件資料載入並建立DataFrame物件,指

令變化如下所示:

上述指令僅簡化表示,在實際讀取文件時,需要給定正確的文件

所在路徑,不論是在OS本地端的檔案系統、或是在HDFS分散式

檔案系統中皆然。

我們可用以下指令來替代上方指令來從事相同的工作:

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

說明範例

我們利用Spark提供的範例來說明如何建立DataFrame,

這些範例在/usr/local/spark/examples/src/main/resources/,

有兩個範例資料people.json和people .txt,內容如下圖所示:

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

示範在PySpark互動環境下建立DataFrame:

首先,啟動命令列視窗,並輸入以下指令以進入PySpark環境:

進入PySpark後,執行以下指令,輸入people.json文件以產生名

為df的DataFrame物件,再利用.show()方法顯示物件的內容:

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

保存DataFrame

使用spark.write這個SparkSession物件方法,將

DataFram物件保存成不同類型的文件目錄,指令變化如

下所示:

上述指令僅簡化表示,在實際寫入文件時,需要給定正確的文件

目錄所在路徑,不論是在OS本地端的檔案系統、或是在HDFS分

散式檔案系統中皆然。

也可用以下指令來替代上方指令來從事相同的工作:

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

前述指令"看似"是產生出新的文件以保存DataFrame物

件。然而,實際上是產生檔案目錄,而不是文件。

在PySpark環境執行下述範例:

先利用Spark提供的範例資料people.json,來建立一個名為

peopleDF的DataFrame物件

接著再將peopleDF中的“name”與“age”這兩個欄位資料,

存入到另一個名為newpeople.json的目錄中。

接著從peopleDF中選取“name”欄,並將該欄資料保存到另一

個名為newpeople.txt的目錄中。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

25

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

以下先建立名為df的示範用DataFrame物件,再進行常

用操作的介紹。

啟動命令列視窗,並輸入以下指令以進入PySpark環境:

進入PySpark後,執行以下指令,輸入people.json文件以產生名

為df的DataFrame物件,再利用.show()方法顯示物件的內容:

DataFrame常用操作

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

printSchema():將指定的DataFrame之架構(即:其

metadata)列出。

上述的nullable = true是指該欄位是否可存空值

select():將DataFrame之某些Column資料列出來。

以下指令將df的"name"欄位資料與"age"欄位資料+1後的結果顯

示出來

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

filter():類似SQL中的"where條件式",做為資料過濾條

件之用。

執行以下指令,將"age"大於20的資料顯示出來。

groupBy():根據某個欄位進行資料分群。

執行以下指令,計數以age為基礎之各個群體的非空資料個數。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

sort():根據某個欄位進行資料升/降冪排序。

執行以下指令,以"age"進行升/降冪排序。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

將RDD轉換成DataFrame的型式,共有兩種做法:

1.使用反射(Reflection)以推斷RDD模式,

2. 使用程式撰寫來指定RDD模式。

以下利用

"/usr/local/spark/examples/src/main/resources/"下的

people.txt做為範例進行操作。people.txt的資料格式如

下所示:

從RDD轉換得到DataFrame

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

利用反射以推斷RDD模式

此方法適用於對已知資料結構的RDD進行轉換。

在PySpark互動環境逐行執行以下指令,以進行RDD模式

推斷與轉換的工作。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

上述2~5行程式碼運作過程如下圖所示:

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

執行結果如下所示

33

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

使用程式撰寫來指定模式

當無法確知資料結構時,就需要採用程式撰寫來指定

RDD模式。

主要的撰寫程序是:

製作表頭

製作表中的記錄

將表頭與記錄結合在一起

回到PySpark互動環境,我們可以逐行執行以下指令以完

成上述工作。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

執行結果如下:

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

使用Spark SQL讀寫資料庫

SparkSQL除了可以支援Parquet、JSON、Hive等資料源

,也可以透過JDBC連接外部的關聯式資料庫。

前置工作

讀取MySQL資料庫中的資料

向MySQL資料庫寫入資料

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

前置工作

假設MySQL資料庫系統已安裝完畢。首先,開啟一個新

的終端機畫面,並輸入下列指令以啟動MySQL服務(需輸

入密碼以驗証身份,密碼:hadoop)。

再執行下列指令,並輸入用戶root的密碼 (密碼:

hadoop),以啟動MySQL Shell模式。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

接著,輸入以下的SQL指令,以完成名為spark的資料庫

與名為student的表格之建立。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

接下來,下載MySQL的JDBC驅動程式,如:mysql-

connector-java-8.0.19.jar

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

接著拷貝到Spark的安裝目錄“/usr/local/spark/jars/”

下,並啟動PySpark環境

41

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

讀取MySQL資料庫中的資料

啟動PySpark後,可以執行以下指令以連接資料庫、讀取

資料庫內的資料,形成DataFrame物件並顯示於螢幕上

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

向MySQL資料庫寫入資料

剛剛在MySQL執行環境下建立了一個名稱為spark的資料

庫,並在該資料庫裡建立了一個名稱為student的表格。

輸入以下的SQL指令以再次確認名為student的表格內的

內容。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

接著,回到PySpark互動環境,逐行執行以下指令,往

spark.student表格中插入兩筆記錄。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

執行完上述指令後,回到MySQL執行環境,輸入以下的

SQL指令看看名為student的表格內容是否有變動。

很明顯地可以看出,student這張表中真的多出了兩列的資料,

而這兩列資料是由Spark新增的。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

46

本章小結

• 本章首先介紹了SparkSQL的起源與發展。

• 接著介紹了SparkSQL的資料模型DataFrame,它是由Schema+RDD

的結構化分散式資料集,相當於關聯式資料庫系統中的二維表格。

• 建構好的DataFrame可以執行一些常用的操作。

• 最後介紹了SparkSQL利用JDBC連接MySQL資料庫系統,以進行資料

讀寫操作。

國立聯合大學 資訊管理學系 巨量資料課程 (陳士杰)

4747

-本單元結束-

感謝您的聆聽