SparkSQL是Spark用來處理結(jié)構(gòu)化數(shù)據(jù)的一個(gè)模塊叨咖,它提供了2個(gè)編程抽象:DataFrame
和DataSet
,并且作為分布式SQL查詢引擎使用。
不同于Hive將HiveQL轉(zhuǎn)換成MapReduce然后提交執(zhí)行,SparkSQL是將SQL語句轉(zhuǎn)換成RDD然后提交集群執(zhí)行春锋,執(zhí)行效率大大提升。
SQL的特點(diǎn)
- 易整合
- 統(tǒng)一的數(shù)據(jù)訪問方式
- 兼容Hive
- 標(biāo)準(zhǔn)的數(shù)據(jù)連接
DataFrame
與RDD類似差凹,DataFrame也是一個(gè)分布式數(shù)據(jù)容器期奔。但是DataFrame更像傳統(tǒng)數(shù)據(jù)庫的二維表格,除了數(shù)據(jù)之外還記錄數(shù)據(jù)的結(jié)構(gòu)信息直奋,即schema。
同時(shí)施禾,與Hive類似脚线,DataFrame也支持嵌套數(shù)據(jù)類型(struct,array和map)弥搞。
從API易用性的角度看DataFrame API提供的是一套高層的關(guān)系操作邮绿,比RDD API要更加友好。
對(duì)于RDD來說攀例,它只關(guān)心是什么類型的數(shù)據(jù):
Person |
---|
Person |
Person |
Person |
而對(duì)于DataFrame船逮,它呈現(xiàn)了數(shù)據(jù)的每一列的名字以及數(shù)據(jù)類型:
Name | Age |
---|---|
String | Int |
String | Int |
DataFrame為數(shù)據(jù)提供了Schema的視圖,可以把它當(dāng)做是數(shù)據(jù)庫中的一張表粤铭,DataFrame也是懶執(zhí)行的挖胃,但是性能要比RDD要高,主要原因是:
- 優(yōu)化的執(zhí)行計(jì)劃:查詢計(jì)劃通過Spark Catalyst Optimiser進(jìn)行優(yōu)化
例如:
users.join(events, users("id") === events("user_id")).filter(events("date") > "2019-12-01")
執(zhí)行計(jì)劃為:
- logical plan
- optimized plan
- optimized plan with intelligent data sources
例子中展示了一個(gè)對(duì)用戶事件分析的操作梆惯。兩個(gè)DataFrame進(jìn)行join后進(jìn)行filter過濾酱鸭,如果按照邏輯計(jì)劃的話會(huì)先進(jìn)行join,再進(jìn)行filter垛吗,而join涉及到了executor間的網(wǎng)絡(luò)傳輸凹髓,是一個(gè)開銷比較大的操作。
而SparkSQL優(yōu)化器則將filter操作下推怯屉,先對(duì)DataFrame進(jìn)行過濾蔚舀,在進(jìn)行join饵沧,這樣就避免了不必要的數(shù)據(jù)的傳輸,提高了性能赌躺。
DataSet
- 是DataFrame API的一個(gè)擴(kuò)展狼牺。
- 用戶友好的API風(fēng)格,既具有類型安全檢查也具有DataFrame的查詢優(yōu)化特性寿谴。
- DataSet支持編解碼器锁右,當(dāng)需要訪問非堆上數(shù)據(jù)是可以避免反序列化整個(gè)對(duì)象,提高了效率讶泰。
- case class可以用來在DataSet中定義數(shù)據(jù)的結(jié)構(gòu)信息咏瑟,類中的每個(gè)屬性名稱直接映射到DataSet中的字段名稱。
- DataFrame是DataSet的特例痪署,
DataFrame=DataSet[Row]
码泞,所以通過as
方法可以將DataFrame轉(zhuǎn)換為DataSet。而Row是一個(gè)類型狼犯,用來定義結(jié)構(gòu)化的一行數(shù)據(jù)余寥。 - DataSet是強(qiáng)類型的。