Spark之SQL解析(源碼閱讀十)

  如何能更好的運用與監控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

  三、使用optimizerResolved LogicalPlan進行優化,生成Optimized LogicalPlan;函數

  四、使用SparkPlanLogicalPlan轉換成PhysiclPlan;工具

  五、使用prepareForExceptionPhysicalPlan轉換成可執行物理計劃。源碼分析

  六、使用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表relationswhere後的表達式group by後的表達式hiving後的表達式排序字段orderingLimit後的表達式。隨之就進行匹配封裝操做RDD,Filter、Aggregate、Project、Distinct、sort、Limit,最終造成一顆LogicalPlan的Tree.

  那麼join操做,也包含了左外鏈接、全外鏈接、笛卡爾積等。

  

  好的,既然sql的執行計劃解析完了,下來該對解析後的執行計劃進行優化,剛纔的解析過程將sql解析爲了一個Unresolved LogicalPlan的一棵樹。下來Analyzeroptimizer將會對LogicalPlan的這棵樹加入各類分析和優化操做,好比列剪枝謂詞下壓啊。

  AnalyzerUnresolved LogicalPlan數據字典(catalog)進行綁定,生成resolved LogicalPlan.而後呢OptimizerResolved LogicalPlan進行優化,生成Optimized LogicalPlan.

  

  這裏的useCachedData方法實際是用於將LogicalPlan的樹段替換爲緩存中的。具體過濾優化看不懂啊TAT 算了。。第一遍源碼,講究先全通一下吧。

  下來,一系列的解析啊、分析啊、優化啊操做事後,由於生成的邏輯執行計劃沒法被當作通常的job來處理,因此爲了可以將邏輯執行計劃按照其餘job同樣對待,須要將邏輯執行計劃變爲物理執行計劃。

  

  以下圖,你注意哦,配置文件中shufflePartition的個數就是從這裏傳進來的。

  

  

  這裏面真正牛逼變態的是BasicOperators。它對最經常使用的SQL關鍵字都作了處理,每一個處理的分支,都會調用planLater方法,planLater方法給child節點的LogicalPlan應用sparkPlanner,因而就差造成了迭代處理的過程。最終實現將整顆LogicalPlan樹使用SparkPlanner來完成轉換。最終執行物理計劃。

  

  

參考文獻:《深刻理解Spark:核心思想與源碼分析》

相關文章
相關標籤/搜索