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

  如何能更好的運用與監控sparkSQL?或許我們改更深層次的瞭解它深層次的原理是什麼。之前總結的已經寫了傳統數據庫與Spark的sql解析之間的差別。那麼我們下來直切主題~

  如今的Spark已經支持多種多樣的數據源的查詢與加載,兼容了Hive,可用JDBC的方式或者ODBC來連接Spark SQL。下圖爲官網給出的架構.那麼sparkSql呢可以重用Hive本身提供的元數據倉庫(MetaStore)HiveQL、以及用戶自定義函數(UDF)序列化反序列化的工具(SerDes).

  下來我們來細化SparkContext,大的流程是這樣的:

  1、SQL語句經過SqlParser解析成Unresolved LogicalPlan;

  2、使用analyzer結合數據字典(catalog)進行綁定,生成Resolved LogicalPlan;

  3、使用optimizerResolved LogicalPlan進行優化,生成Optimized LogicalPlan;

  4、使用SparkPlanLogicalPlan轉換成PhysiclPlan;

  5、使用prepareForExceptionPhysicalPlan轉換成可執行物理計劃。

  6、使用execute()執行可執行物理計劃,生成DataFrame.

  這些解析的過程,我們都可以通過監控頁面觀察的到。

  下來我們先從第一個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:核心思想與源碼分析》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章