今天是Catalyst部分的收官,主要講一些雜項內容。算法
什麼叫外部數據源,是SparkSql本身支持的一些文件格式,以及一些本身自定義格式的文件開發。數據庫
讓咱們從文件的讀取api開始,能夠看到最終會建立一個DataFrame,當中比較關鍵的是relation方法。
編程
首先,會以反射方式獲取provider。
json
咱們以json文件爲例,其provider爲json.DefaultSource。能夠看到繼承自HadoopFsRelationProvider。
api
進入其處理,能夠看到,首先是獲取文件路徑,其後是調用了createRelation方法。
緩存
讓咱們進入json.DefaultSource的createRelation,建立了JSONRelation。
服務器
JSONRelation繼承自HadoopFsRelation,來自interfaces.scala,定義了對各種文件的處理接口。
markdown
最終JSONRelation組合入LogicalRelation中,提供後續解析器處理。
數據結構
簡單來講,處理流程是:jvm
在optimizer中,對於文件的操做,在執行過程當中還支持過濾下推,根據算子生成下推條件。
filters中定義了一系列算子,能夠在服務器上直接過濾數據,而不是集中到客戶端過濾。
咱們看下緩存,不少算法都是緩存+並行來作的,是一個開發者逃不掉的魔咒,在Catalyst中直接cacheTable就能夠緩存。
緩存在內存中,是以什麼方式存儲的?確定是列式存儲的方式,由於列式存儲檢索數據特別快,不是RDD一行一行object存放的方式,緩存的時候,對象會進入jvm的老年代,很容易產生full GC,進行交互查詢容易悲劇。基於列的話,就能夠採用相似byteBuffer這樣的方式,因爲是一樣的數據類型,能夠進行壓縮,內存佔用會極大的減小。查詢的時候,只使用部分列也是一個天然的思路。
讓咱們看一下代碼:首先進入cacheTable方法。
最重要的是對InMemoryRelation的生成。
InMemoryRelation繼承自LogicalPlan,其方法都是一些簡單的基於字節的編程
內部作cache的時候,根據構建的樹,會採用mapPartitions的方式。
具體在partition裏面,會迭代數據生成新的iterator,是ByteBuffer構成的array,對於每一個列都會變成array的一部分,在遍歷沒一行數據的時候,都會變成列,每一列數據都會存入byteBuffer,
最後仍是會調用rdd的persist。
這個看起來有點像高性能的內存數據庫,在進行表的查詢時,把內存數據結構的分區進行具體的掃描操做,根據查詢表達式創建索引,經過掃描器accessor得到具體的數據。
Catalyst支持讓咱們本身採用udf、udaf的方式去擴展功能,catalyst在分析的時候,會支持這方面的功能,由functionRegistry來進行管理。
能夠看到FunctionRegistry中主要是一些管理類方法。
到此,Catalyst中比較重要的功能都已解析完畢。
DT大數據天天晚上20:00YY頻道現場授課頻道68917580