Spark SQL你不得不知道的那些事兒

專欄其他相關文章:Spark環境部署;Spark生態圈;Hive - 建立在Hadoop架構之上的數據倉庫;數據倉庫Hive的使用;分散式計算框架MapReduce;YARN 分散式資源調度;hadoop分散式文件系統HDFS;Hadoop的一些基本命令使用

*Spark SQL的發展

*SQL on hadoop常用框架

*Spark SQL概述

*Spark SQL願景

*Spark SQL架構

No.1 Spark SQL的發展

*為什麼需要SQL

1、事實上的標準

  • 很多傳統的dba人員或者熟悉關係新資料庫的人在遇到日益增長的數據量,關係型資料庫已經存儲不了那麼多信息,那麼如果想要使用大數據的手段來進行處理,那麼一大批人肯定還是有SQL那最好,如果你要使用mapreduce或者spark,那麼這些框架對傳統的dba的同學來說,門檻比較高,要麼你要學java,要麼你要學python 或者Scala編寫程序,這個成本還是很高的,如果能把原來關係型資料庫的那一套拿到大數據中那是最好的。

2、易學易用

  • 對於SQL來說,任何一個稍有基礎的人花個兩三天都能學會如何使用,學習成本也比較低。

3、受眾面廣

  • 這一點不用多說,用的實在太多了。

*shark

1、shark其實已經不怎麼用了,但是要對spark sql有更多了解的話,還是需要知道shark的。

既然說到shark就不得不說hive:這是基於hadoop之上的一個開源的工具,他提供的就是類似於SQL的一種HQL語言,它的好處就是可以直接把你的SQL語句轉換成mapreduce作業,然後提交在集群上運行,好處就是我們不需要基於mapreduce的api進行編程,你只需要寫SQL語句就能完成大數據的統計和分析。

這個最大的優勢就是對於不太熟悉編程語言的人來說,也不用了解太多mapreduce底層的東西就能對存儲在HDFS上的海量數據進行分析和查詢,當然這也是有缺點的:hive是把sql翻譯成mapreduce作業,所以底層還是基於mapreduce,那麼mapreduce框架的缺點就是效率太低,那麼這樣子我們hive 的效率肯定不會高,對於批處理的作業hive進行實現的話,如果很大的話,耗時十幾個小時都是很可能的。那麼缺點這麼明顯,hive有沒有改進呢?肯定也有,你不是慢嘛,那我把你底層的執行引擎換掉,後來就產生的TEZ還有spark這些底層的執行引擎,也就是說hive可以跑在TEZ、SPARK上面。

後來慢慢發展就推出了spark,spark是一個基於內存的分散式計算框架,他的執行效率比mapreduce高了太多。

這個時候就有人提出能不能讓我們的hive on spark,就是hive跑在spark上,後來就誕生了shark,其實和原來的hive on mapreduce一樣就是把底層的執行引擎改掉了,現在讓hive跑在spark上面了,shark剛剛推出的時候有一個別稱就是hive on spark,但是現在的hive on spark已經不僅僅是特指shark了,shark產生的目的就是為了讓hive跑在spark之上。

2、hive on spark的本質也很簡單,就是現在解析還是交給hive,但是我們hive原來是翻譯成mapreduce作業,現在shark是把sql翻譯成RDD來執行,RDD是spark核心的編程組件。

那麼shark剛剛推出的時候很受歡迎,因為能夠使得原來的hive作業跑的更加快,原因是因為基於spark這個分散式的基於內存的計算框架,還有一個是因為基於內存的列式存儲,列式存儲能夠很大的提升我們大數據場景當中數據處理和分析的性能。

3、與hive能夠兼容,原來你的作業是hive運行的,現在你的底層改成spark,但是原來的作業並不需要任何的改造,但是也有缺點,邏輯執行計劃生成、執行計劃的優化、hive ql的解析是依賴於hive的,而shark僅僅只是把物理執行計劃從mapreduce作業替換成spark作業,所以他對這個hive的依賴性太大了,那麼依賴過大導致你要添加一些新的功能的話就非常非常不方便了,那麼mapreduce他是基於進程的並行的處理的,所以hive裡面很多代碼並沒有注意線程安全問題,但是spark是基於線程的,這樣子就導致shark不得不只用一套單獨的維護了打了補丁的hive的分支才行,他是沒有辦法合併到hive裡面去的,他必須要額外的來維護一個分支。這個就導致了他後面的發展受到了很嚴重的限制。那麼到現在我們對shark也有了一定的了解。

4、shark的終止:

這張圖實在2014年7月份在spark峰會上提出來的,當時決定終止了對shark的開發,後期就把重點全部放在Spark SQL上面,Spark SQL是什麼呢?對於Spark來說它是一個新的SQl執行引擎,這張圖右邊還有一個hive on spark,它能夠幫助hive用戶慢慢過渡到Spark上面來。

shark終止以後,產生了兩個分支:

1)hive on spark

hive社區的,源碼是在hive中的

2)Spark SQL

Spark社區,源碼在Spark中,支持多種數據源,多種優化技術,擴展性好很多

兩者區別:Spark SQL剛開始也是使用了hive裡面一些東西的,但是Spark SQL裡面的hive版本肯定要比hive社區理的版本要低一些的,那麼hive裡面有的東西,比如說原來跑在mapreduce之上已有的一些功能,如果你使用hive on spark的話他是能支持的,但是有一些功能想要直接在Spark SQL上直接用,很可能是沒有辦法支持,因為Spark SQL裡面的一些功能並沒有hive完善,畢竟hive已經這麼多年,而Spark只是發展了這兩三年而已。那麼shark終止以後,在Spark界重心就已經在Spark SQL上了,Spark SQl乾的事情和原來的shark是有很大的差別的,因為原來的shark依賴了很多hive的東西,那麼在sparksql裡面就必須要把這個依賴更好的減輕。

No.2 SQL on hadoop常用框架

首先都是基於hadoop的,有hive、spark、presto、drill、impala

1、HIVE

hive應該使用的最多,80%的離線處理都是hive,他是最原始的sql on hadoop的方案,他是由facebook提出來的,它的原理是將SQL語句轉換成mapreduce作業。他還有一個metastore的概念,就是元數據,這個元數據在後面其他的框架裡面也有,iimpala、spark裡面也有,如果大家都用相同的一份metastore的話,那就有一個好處,你hive裡面創建的表在spark裡面也可以訪問,impala裡面也能訪問。

2、Impala

這是由cloudera開發:我們常用的cdh的hadoop的版本以及Hbase等等,他都有提供很好的兼容,這個建議在生產上使用的hadoop系列,因為它解決了很多版本之間的依賴關係,還有cm,cm是什麼呢,其實就是提供了一個web的界面,就是你如果想安裝hadoop或者hive或者hbase等等相關的東西,你不需要通過Linux命令操作,只需要在圖形化的界面上面通過瀏覽器一步一步往下點就能很快的搭建一個hadoop生態系統裡面的框架都是可以的,這個對於Linux小白還是很方便的。他也有一個metastore的概念。

它提供的功能也是一樣,也是寫SQL的,但是不是將SQL運行在mapreduce上面的,他自己有一些進程的,他的執行效率比hive是要提升很多的,但是有一點,他是基於內存的,所以對內存的要求是比較高的。

3、Presto

這個也是由Facebook開源的,也是使用SQL的,國內的話,京東用的是非常多的。

4、Drill

近兩年還有一個Drill,這是一個互動式的,也是支持sql的框架,而去還能直接訪問Hdfs上得數據,還有你關係型資料庫里的數據,還有一些json的格式都能夠訪問,還有hbase,mongdb以及S3(amazon的存儲系統),這些他都是能夠訪問的,而去也能訪問hive裡面的表,功能是非常的強大,近兩年非常火。

5、Spark SQL

支持SQL,但不僅僅寫SQL這麼簡單,還能基於dataframe或者是dataset api進行編程,他也是有metastore,也就是說你 hive裡面的表你直接使用sparksql直接訪問也是可以的,還支持直接訪問hdfs、rdbms、json、hbase、mongdb、s3、hive。那麼這裡還有一個概念就是外部數據源。

No.3 Spark SQL概述

Spark SQL自從面世以來不僅接過了shark的接力棒,為spark用戶提供高性能的SQL on hadoop的解決方案,他還為spark帶來了通用的高效的,多元一體的結構化的數據處理能力。

1、spark sql 是spark中的一個核心組件,並且是在2014年4月份spark1.0版本的時候發布的

我們看上圖,左邊那張圖描述的是2014年3月到2015年6月份,參與Spark的源碼修改的數量是直線增長的,這說明Spark社區是非常的活躍的!,右邊的這張圖描述的是14年3月到15年5月,每月提交的Commits的數量,其實也是快速增長的,這兩張圖是15年的時候截取的,現在的數量增長的已經更快了,Spark SQL是除了Spark core之外最受關注的一個組件,而且Spark SQL模塊代碼的貢獻數量華人是非常非常多的,我們看下面那張藍色圖,說在spark1.3版本當中正式從Alpha階段畢業,這什麼意思啊?也就意味著他的api或者功能已經比較穩定了,可以放心在生產中使用。如果你看到一個框架或者模塊他是Alpha版本的話,那麼建議不要再生產當中使用,可以做一些嘗試性的使用是可以的,生產商使用肯定是有很大的風險的。

2、Spark SQL能運行SQL以及hive ql的查詢,還能運行UDFs、UDAFs以及序列化和反序列化

這個SQL語句,當然這不是真正的SQL語句,這是一個示範的語句,他是hive裡面的一個語句,那麼這個語句可以直接在Spark SQL上面進行訪問是沒有問題的,因為Spark SQL他是做為shark的繼任者,那麼主要功能之一就是能夠方便的操作現在已經有的hive數據。

3、它能夠連接到已經存在的BI的工具通過JDBC的方式

我們看,右邊是已經存在的第三方的一些工具,對於這些工具裡面的數據,他可以通過JDBC或者ODBC的方式直接將Spark SQL連接上去,這樣就可以藉助Spark進行快速的處理數據。

4、它能夠支持python、java、Scala、R語言

5、好了,說了這麼多,我們進到官網看看官網怎麼說的。進到官網點Libraries下面的SQL and DataFrames。

其中有這麼一句話很重要。

Spark SQL is Apache Spark"s module for working with structured data.

他說spark是apache的一個模塊,這個模塊用來處理結構化的數據,什麼是結構化的數據,你可以理解為文本文件、json啊這些都是結構化的數據,從這個層面來看有見到SQL字樣嗎?沒有是不是,他說的是處理結構化的數據的,我們繼續看,等會再講解這個問題。

1)看上圖第一個標題集成,上面說可以無縫的使用SQL的查詢在我們spark的應用程序裡面,sparkSQL可以讓你查詢結構化的數據在spark應用程序上面,當然你可以使用SQL的API,也可以使用dataframe的API它支持四種語言,我們看右邊,其中HiveContext可以理解為處理hive相關的上下文,可以把hive里的數據進行讀取或者是其他的操作。

2)第二個標題數據訪問方式,他可以使用相同的方式連接到外部數據源,這就是外部數據源,是SparkSQL里買非常重要的功能。dataframe和SQL提供了一個通用的方式來訪問各式各樣的數據源,包括Hive, Avro, Parquet, ORC, JSON, and JDBC,我們可以看右邊的小圖,讀取json文件,裡面的s3n是什麼?就是amazon的s3數據存儲系統,可以把這個文件讀取進來然後註冊成一張表就是圖中的.registerTempTable("json"),註冊成一個臨時表,然後後面的所有操作都可以針對這個臨時表來進行操作,這對於SQL的人來說是一個非常大的福音。

3)我們繼續往下看,我們看上圖hive的兼容性(Hive Integration),它能夠在已有的數據上運行沒有做任何修改的hive查詢,也就是說你hive現在有的東西,你可以直接拿來在sparkSQL上面運行,他是兼容的。為什麼呢?因為sparkSQL復用了hive的前端以及元數據

4)再往下是標準的連接,它能夠使用JDBC或者ODBC的方式來連接到你外部的其他的BI的工具上面,這也是很常用的。

6、從嚴格意義上來說sparkSQL不僅僅是SQL

更加準確的來說,他是超乎SQL的

為什麼這麼說呢?前面我們說到,spark是apache的一個模塊,這個模塊用來處理結構化的數據,從這個層面來看有見到SQL字樣,他並沒有強調SQL,其實sparkSQL它不僅僅有訪問或者操作SQL的功能,還提供了其他的非常豐富的操作:外部數據源、優化。

我們繼續再看官網最新的文檔,然後在導航條找到編程指南去看dataframe datasets and SQL

我們找到概述這裡。

文檔上說sparkSQL是處理結構化數據的模塊,這個說過了,他與基本的RDD編程是不一樣的,那麼sparkSQL提供了一些介面,這些介面可以提供給spark更多的信息包括數據的結構化以及在計算層面的執行都做了很多的優化,那麼事實上,SparkSQL能夠使用到這些額外的信息做到更加底層的額外的優化,我們有非常多的方式與sparkSQL進行交互,包括你可以使用SQL也可以使用dataset API。那麼我們對sparkSQL做一個總結。

Spark SQL概述小結:

1)Spark SQL的應用並不局限於SQL;

2)訪問hive、json、parquet等文件的數據;

3)SQL只是Spark SQL的一個功能而已;

===> Spark SQL這個名字起的並不恰當

4)Spark SQL提供了SQL的api、DataFrame和Dataset的API;

No .4 Spark SQL願景

*寫更少的代碼

*讀更少的數據

註:這個更少的數據是指通過一些優化手段使得Spark SQL這個執行引擎能自動的給我們去除掉一些不必要的數據,然後再進行運行,比如你讀一個很大的文件,和讀一個很大文件的子集的數據,那麼第二個運行起來肯定是更快的。

*把優化的工作交由底層的優化器運行

註:把優化工作拿掉,我們並不需要做一些優化工作,也就是小白和高手寫出來的應用程序最後的執行效率都是一樣的。

為了達成這三點,在sparkSQL1.3版本裡面,他引入了一個非常重要的概念,就是dataframe,當然dataframe不是sparkSQL裡面獨有的,他是從R語言和python語言裡面給引進過來的,延續了傳統的單機數據開發的一個體驗,並把它推廣到分散式的大數據場景當中來使用,讓我們覺得是在寫單機應用程序,但是寫出來的程序能夠在分散式的場景進行使用的

No.5 Spark SQL架構

sparkSQL架構分成三個部分,第一部分是前端的,第二部分是後端的,對三個部分是中間的Catalyst,這個Catalyst是整個架構的核心。

1、首先我們看前端。前端有不同種的訪問方式。

1)典型的我們可以使用hive,你hive過來就是一個SQL語句,SQL語句就是一個字元串,那麼這個字元串如何才能夠被Catalyst進行解析呢,或者說如何將一個SQL語句翻譯成spark的作業呢,他要經過解析的,有一個抽象語法樹,這是第一種訪問方式。

2)第二種訪問方式,我們可以通過spark的應用程序,編程的方式來操作,編程的時候我們可以使用SQL,也可以使用dataframe或者是dataset api。

3)第三種是Streaming SQL,也就是說流和SQL綜合起來使用。

2、我們看Catalyst

1)前端三個訪問方式,當前端過來以後他首先會生成一個Unresolved Logical Plan,也就是一個沒有徹底解析完的一個執行計劃,這個執行計劃會和我們的元數據,也就是metastore裡面的schema一個表信息進行整合然後生成一個Logical Plan(邏輯執行計劃)。

2)那麼這個邏輯執行計劃是最原始的,中間還會做各種優化也很多規則作用上去,也就是圖中的Optimization Rules,然後進行優化以後生成優化過後的邏輯執行計劃,就是圖中的Optimized Logical Plan。

3)那麼邏輯執行計劃生成完了以後,才會生成物理執行計劃,也就是我們spark的一個作業。

那麼從你的SQL語句解析成抽象語法樹之後後續的部分全部交給Catalyst來完成,包括你邏輯執行計劃的生成,邏輯執行計劃的優化都是由Catalyst完成的,我們再回顧一下shark,他的解析然後邏輯執行計劃的生成和優化全部都是依賴於hive的,那麼這就是sparkSQL和hive典型的一個區別從抽象語法樹之後,也就是圖上AST之後完全由sparkSQL里的Catalyst接管以後,由他來生成物理執行計劃,並最終提交到生產上面去運行就行了。

3、以上就是sparkSQL架構的整體的流程,這個流程當中主要有幾個部分,語法樹、邏輯執行計劃、優化之後的邏輯執行計劃、物理執行計劃。如果熟悉SQL的執行流程或者了解hive的SQL語句是怎麼樣從SQL翻譯成mapreduce作業的話,那麼其實你會看出來整個流程都是非常相似的,那麼在SQL on hadoop框架裡面的那麼多框架,只要是基於SQL的,他的大概流程都是這樣子的,從SQL解析過後成為一個抽象語法樹,然後再到了邏輯執行計劃,然後邏輯執行計劃優化,再到物理執行計劃,再到物理執行計劃的優化,最終生成你對應框架的作業,有可能是mapreduce作業,可能是spark作業,提交到對應的集群上運行就可以了。

到此 Spark SQL你不得不知道的那些事兒就寫到這裡了!這幾天寫文章寫的手都要掉了。。。。。。


推薦閱讀:

Python實現Zip文件的暴力破解
Python篇-多進程與協程的理解與使用
如何踏上人工智慧之路(機器學習篇)
【強烈推薦】十三個鮮為人知的大數據學習網站
普通人為什麼要學習Python?

TAG:编程 | 程序员 | Python |