如何能更好的運用與監控sparkSQL?或許咱們改更深層次的瞭解它深層次的原理是什麼。以前總結的已經寫了傳統數據庫與Spark的sql解析之間的差異。那麼咱們下來直切主題~sql
現在的Spark已經支持多種多樣的數據源的查詢與加載,兼容了Hive,可用JDBC的方式或者ODBC來鏈接Spark SQL。下圖爲官網給出的架構.那麼sparkSql呢能夠重用Hive自己提供的元數據倉庫(MetaStore)、HiveQL、以及用戶自定義函數(UDF)及序列化和反序列化的工具(SerDes).數據庫
下來咱們來細化SparkContext,大的流程是這樣的:緩存
一、SQL語句通過SqlParser解析成Unresolved LogicalPlan;架構
二、使用analyzer結合數據字典(catalog)進行綁定,生成Resolved LogicalPlan;app
三、使用optimizer對Resolved LogicalPlan進行優化,生成Optimized LogicalPlan;函數
四、使用SparkPlan將LogicalPlan轉換成PhysiclPlan;工具
五、使用prepareForException將PhysicalPlan轉換成可執行物理計劃。源碼分析
六、使用execute()執行可執行物理計劃,生成DataFrame.優化
這些解析的過程,咱們均可以經過監控頁面觀察的到。spa
下來咱們先從第一個Catalog開始,什麼是Catalog?它是一個字典表,用於註冊表,對標緩存後便於查詢,源碼以下:
這個類呢,是個特質,定義了一些tableExistes:判斷表是否存在啊,registerTable:註冊表啊、unregisterAllTables:清除全部已經註冊的表啊等等。在建立時,new的是SimpleCatalog實現類,這個類實現了Catalog中的全部接口,將表名和logicalPlan一塊兒放入table緩存,曾經的版本中呢,使用的是mutable.HashMap[String,LogicalPlan]。如今聲明的是ConcurrentHashMap[String,LogicalPlan]
而後呢,咱們來看一下詞法解析器Parser的實現。在原先的版本中,調用sql方法,返回的是SchemaRDD,如今的返回類型爲DataFrame:
你會發現,調用了parseSql,在解析完後返回的是一個物理計劃。
咱們再深刻parse方法,發現這裏隱式調用了apply方法:
下來咱們看一下,它的建表語句解析,你會發現其實它是解析了物理計劃,而後模式匹配來建立表:
最後調用了RefreshTable中的run方法:
那麼建立完表了,下來開始痛苦的sql解析。。。上傳說中的操做符函數與解析的全部sql函數!
一望拉不到底。。。這個Keyword實際上是對sql語句進行了解析:
而後拿一個select的sql語法解析爲例,本質就是將sql語句的條件進行了匹配,過濾篩選:
一個select的步驟包括,獲取DISTINCT語句、投影字段projection、表relations、where後的表達式、group by後的表達式,hiving後的表達式、排序字段ordering、Limit後的表達式。隨之就進行匹配封裝操做RDD,Filter、Aggregate、Project、Distinct、sort、Limit,最終造成一顆LogicalPlan的Tree.
那麼join操做,也包含了左外鏈接、全外鏈接、笛卡爾積等。
好的,既然sql的執行計劃解析完了,下來該對解析後的執行計劃進行優化,剛纔的解析過程將sql解析爲了一個Unresolved LogicalPlan的一棵樹。下來Analyzer和optimizer將會對LogicalPlan的這棵樹加入各類分析和優化操做,好比列剪枝啊 謂詞下壓啊。
Analyzer將Unresolved LogicalPlan與數據字典(catalog)進行綁定,生成resolved LogicalPlan.而後呢Optimizer對Resolved LogicalPlan進行優化,生成Optimized LogicalPlan.
這裏的useCachedData方法實際是用於將LogicalPlan的樹段替換爲緩存中的。具體過濾優化看不懂啊TAT 算了。。第一遍源碼,講究先全通一下吧。
下來,一系列的解析啊、分析啊、優化啊操做事後,由於生成的邏輯執行計劃沒法被當作通常的job來處理,因此爲了可以將邏輯執行計劃按照其餘job同樣對待,須要將邏輯執行計劃變爲物理執行計劃。
以下圖,你注意哦,配置文件中shufflePartition的個數就是從這裏傳進來的。
這裏面真正牛逼變態的是BasicOperators。它對最經常使用的SQL關鍵字都作了處理,每一個處理的分支,都會調用planLater方法,planLater方法給child節點的LogicalPlan應用sparkPlanner,因而就差造成了迭代處理的過程。最終實現將整顆LogicalPlan樹使用SparkPlanner來完成轉換。最終執行物理計劃。
參考文獻:《深刻理解Spark:核心思想與源碼分析》