春蔚專訪--MaxCompute 與 Calcite 的技術和故事

摘要:2019大數據技術公開課第一季《技術人生專訪》,來自阿里雲計算平臺事業部高級開發工程師雷春蔚向你們講述了MaxCompute 與 Calcite 的技術和故事。 具體內容包括: 1) 什麼是查詢優化器;2)MaxCompute查詢優化器的具體實踐;3)MaxCompute後續計劃;4)從校招到阿里巴巴工程師到Calcite committer,他經歷了怎樣的我的成長。

如下內容根據演講視頻以及PPT整理而成。css

1、查詢優化器簡介

你們都知道,數據庫通常由三部分組成,分別是解析器、優化器和執行引擎。一個SQL進入數據庫後首先須要經過解析器進行解析,生成相應的關係表達式,而後再通過優化器優化生成物理執行計劃,最後由執行引擎執行。優化器是數據庫的重要組成部分,它是數據庫中用於把關係表達式轉換成執行計劃的核心組件,在很大程度上決定了一個系統的性能。假如把數據庫比做人類的「身體」,優化器就是人類的「大腦」,這個大腦決定了人體系統能走多遠、走多快。算法

查詢優化器主要分爲兩種:sql

  • 基於規則的優化器(Rule Based Optimizer,簡稱RBO):根據優化規則將一個關係表達式轉換成另一個關係表達式,同時原有表達式被放棄,通過一系列轉換生成最終執行計劃。事實上,RBO是一種比較落後的優化器,它只認規則,對數據不敏感;容易陷入局部優可是全局差的場景;同時受規則順序影響而產生不一樣執行計劃
  • 基於代價的優化器(Cost Based Optimizer,簡稱CBO):根據優化規則對關係表達式進行轉換,同時原有表達式也會保留,通過一系列轉換後會生成多個執行計劃,以後計算每一個執行計劃的Cost,從中挑選Cost最小的執行計劃做爲最終執行計劃。CBO的優勢是靈活智能,它能根據數據的特色生成相應的執行計劃。所以,目前各大數據庫和計算引擎都傾向於使用CBO,例如從Oracle 10g開始,Oracle已經完全放棄RBO,轉而使用CBO,而Hive在0.14版本中也引入了CBO。MaxCompute 也經歷了從RBO到CBO的過程,這也是MaxCompute 1.0到2.0過程當中一個重大的改變。

CBO主要有兩種不一樣風格的框架,一種是System-R風格,另外一種是Volcano/Cascade風格。數據庫

  • System-R:sql statement通過Parser和Resolver後,首先進行查詢改寫,再經過優化器經過動態規劃算法生成最後的物理執行計劃,最後交由執行器執行。這種風格的CBO最先由IBM的數據庫使用,以後被Oracle和PostgreSQL使用。
  • Volcano/Cascade:Volcano/Cascade與System-R 的不一樣點在於,前者的物理優化器是Top-down,然後者是Bottom-up。Volcano/Cascade基於必定的規則體系(邏輯規則+物理規則)來生成比較好的物理執行計劃。這種風格目前被SQL Server、Apache Calcite和Pivotal所使用。

Apache Calcite 是一個獨立於存儲與執行的SQL優化引擎,目前普遍應用於開源大數據計算引擎中,如 Flink、Drill、Kylin等。Calcite的目標是「一種方案適用於全部需求場景」,旨在爲不一樣的計算平臺和數據源提供統一的查詢引擎。如上圖所示,Calcite的架構不包括存儲和執行。總體流程是一個SQL statement經過JDBC Client進入JDBC Server後,通過SQL Parser 和Validator後生成關係代數表達式(Operator Expressions)。除此以外,用戶還可使用Expressions Builder生成SQL的關係代數表達式,這適用於有本身特定語法的系統。生成的關係代數表達式會進入查詢優化器核心引擎(Query Optimizer),負責執行動態規劃算法和Cost計算。Calcite還提供一些可插拔的功能,如Metadata Providers(爲優化引擎提供Metadata)和Pluggable Rules(支持用戶自定義優化規則)。緩存

Calcite 主要提供了兩種優化器的實現:架構

  • HepPlanner:它指的是前面提到的RBO的實現,它是一個啓發式的優化器,按照規則進行匹配,直到達到次數限制(預先設置的match次數限制)或者遍歷一遍後再也不出現 rule match的狀況纔算完成;
  • VolcanoPlanner:它指的是前面提到的 CBO 的實現,它會一直迭代 rules,直到找到 cost 最小的計劃。

2、MaxCompute查詢優化器實踐

MaxCompute SQL優化器的整體框架以下圖所示,主要包括五部分:
框架

  • 代價模型(Cost Model):用於計算Cost來選擇最優的執行計劃。一個好的代價模型可能會影響整個系統的性能。代價模型是一個五元組,包括CPU、IO、Row Count、Memory、Network。每一個operator只關注於自身的Cost,整個執行計劃的Cost由引擎累積獲得。代價模型力求可以反映客觀的物理實現,如具體的IO、Network值,但不須要獲得和真實如出一轍的數據,只須要可以保證選出較優的執行計劃便可。
  • 優化規則:不一樣的系統有不一樣的優化規則,如分區裁剪規則等。
  • 統計信息:該部分對於優化器來說很是重要,缺少或很差的統計信息可能會致使生成的執行計劃效果比較差。
  • 查詢優化引擎:使用的是Calcite,實現了分區裁剪、鏈接順序的旋轉以及實現算法(如動態規劃算法)的選擇。
  • 基於歷史的資源分配優化: 執行器執行完任務後,會將執行結果反饋給該模塊,由該模塊進行資源分配優化。

MaxCompute SQL優化器基於上述優化引擎實現了Shuffle Removal的功能。Shuffle指的是數據從上游任務(Task)到下游任務(Task)被處理的過程,包括分片、排序等。若是上游任務的數據已經包含了相應的物理屬性,則不必進行shuffle處理。ide

舉個例子,假如須要統計在2018年後建立的部門其中30歲以上員工的平均年齡,使用MaxcCompute能夠獲得如上圖所示的物理執行計劃。首先從員工表emp中過濾出30歲以上的員工,而後從部門表dept中過濾出2018年以後建立的部門,再進行join操做。考慮到數據量可能會比較大,選用Merge join進行操做。因爲須要保證數據分發到同一臺機器上,所以從上游Filter到Merge join須要Shuffle的處理過程(圖中的EX)。此外,join以後的數據須要進行aggregate聚合操做(圖中的Agg)來計算平均年齡,也須要進行Shuffle。事實上,由於以前使用的是Merge join,該過程已經作了數據的分佈和排序工做,因此從join到aggregate的過程當中Shuffle就再也不須要重複去作。面對這類重複的Shuffle過程,能夠經過Shuffle Removal功能去掉。函數

Shuffle Removal功能的實現依靠的是Enforcer Rule, 具體流程以下圖所示。操做符如join,aggregate等要求Input數據必須具有物理數據屬性Trait(經過排序、分片等操做得到),Enforcer Rule能夠保證Input數據所須要的物理屬性(Required Trait):1) 若Input數據不具有Required Trait,則須要增長Shuffle過程;2)若Input數據自己已經知足Required Trait,則無需添加;3)Input能夠進行特性傳遞,即將Required Trait下推到本身的Input中。Shuffle Removal功能上線後已經爲阿里雲帶來了大約10%的資源節省。性能

3、Maxcompute SQL新功能介紹

MaxCompute在阿里巴巴承接了99%的計算和存儲,同時也關注提升外部用戶的用戶體驗和計算效率。接下來要介紹的是MaxCompute 2.0的新功能,主要包括編譯器、開發利器Studio、幫助提高開發效率的過程化支持功能(如腳本模式、參數化視圖)以及自定義功能(如UDT、外表)。在這裏須要提到的是,因爲公共雲還沒有正式發佈,如需使用,可搜索釘釘羣號11782920,聯繫羣主晉恆進行使用。

編譯器

MaxCompute 2.0中編譯器目前有三個主要的新功能:1)全部的編譯錯誤包含行列號信息,從而幫助用戶清晰地瞭解錯誤的位置;2)同義詞編譯中的多個錯誤會經過錯誤報告的形式一次性報出來,方便用戶進行修改;3)支持warning,提示用戶潛在的問題,如Double = STRING精度受損,該功能須要經過set odps.compiler.warning.disable=false預先打開。以上三個功能在開發中很是實用,將極大提升用戶的開發效率。

Studio

第二個須要強烈推薦的是Maxcompute 2.0的Studio。做爲一款IDE,用戶能夠經過它來編寫腳本,其好處主要包括如下幾點(以下圖所示):

1)做業監控:提供詳細而直觀的做業流程圖,用戶能夠方便地查看任務流程以及總體的執行計劃(左上角子圖);
2)做業分析:提供與做業分析相關的數據信息(左下角子圖),如每個任務中Operator的執行時間,經過這些信息,用戶能夠很直觀地看到那部分計劃執行得很差,哪部分的資源佔用比較高、執行時間比較長,從而進行定向調優,有的放矢地提高執行計劃的效率;
3)實時提示SQL中的錯誤,而且能夠一次性提示全部錯誤和警告,提示用戶寫的SQL哪裏有問題(右上角子圖);
4)智能提示:根據用戶輸入的部分字母以及上下文判斷並提示用戶可能要輸入的命令,幫助用戶方便地自動補齊代碼(右下角子圖)。

腳本模式

問題場景:當面臨處理邏輯很複雜的項目時,須要提取多個表後對這些表進行join操做,而後再對結果進行join操做。此外還須要從不一樣的運行階段輸出多個表,即便使用CTE(Common Table Exclusion)也沒法表達,這種狀況下只能將這些步驟拆分爲多個做業順序提交。這種解決方案的複雜度和維護成本都比較高,同時給性能帶來很大影響。

腳本模式解決方案:針對這種需求,MaxCompute 2.0提供了腳本模式的功能。仍是之前面提到的例子(統計在2018年後建立的部門中30歲以上員工的平均年齡)來介紹腳本模式的使用,經過MaxCompute的腳本模式,全部命令能夠寫在一個SQL文件中,用戶首先能夠定義一個變量a,從員工表emp中篩選年齡大於30歲的員工列表;而後定義一個變量b,從部門表dept中篩選建立時間在2018-01-01以後的部門列表;其次定義一個變量c,統計這些部門中30歲以上員工的平均年齡。所獲得的結果能夠經過腳本模式很方便地進行後續處理,好比直接經過多個腳本命令將所需的結果插入到不一樣的表中(具體命令以下圖所示)。在面對很是複雜的查詢時,使用這種方式使得查詢操做和後續的操做更加易於維護、更加清晰。

腳本模式主要有如下三方面的優勢:

  • 複雜性低:以腳本爲單位提交查詢,適合提交複雜的查詢;
  • 易用性高:符合開發者的思考過程,適合編寫複雜邏輯;
  • 性能高:充分發揮優化器能力(基於代價,腳本複雜越有優點)。

參數化視圖

問題場景:假設用戶作了一個視圖給其餘團隊用,功能是讀取一個數據表,運行新寫的模式識別算法提供廣告推薦建議。其餘團隊發現該用戶的算法很好也想用,可是底層訪問的數據表不同,一些模式識別的參數也不同,只好給他們再作一個新的視圖。後來發現原來的視圖有bug,只有一個個的修改,給維護帶來了很大的複雜性。

參數化視圖解決方案:針對這種狀況,MaxCompute 2.0提供了參數化視圖的方式來解決。其語法相似於建立普通的視圖view,不一樣點是參數化視圖的建立須要用到兩個參數,一個是表參數@a(自己包含兩個參數k,v)和String參數@b。參數化視圖的建立命令以下圖所示,其中建立過程結合了腳本模式。能夠發現,經過這種方式建立的視圖能夠很方便地給任何用戶來使用,由於其模式相同,只有參數類型不一樣而已。

自定義功能(UDT)

問題場景:Hive和MaxCompute中均可以寫UDF來知足某些沒有內建函數的需求。好比須要實現一個JSON字符串解析的功能,這個功能用其餘語言實現很是簡單,好比用Java可能只須要一次調用JSON函數就行了,可是MaxCompute的內置函數沒有實現這一功能,爲此寫一個UDF複雜性過高。

UDT解決方案:針對上述問題場景,MaxCompute2.0提供了UDT(User Defined Type)功能,容許用戶在SQL中直接引用第三方語言的類或者對象,獲取其數據內容或者調用其方法 。對於上述問題,只須要以下SQL就能解決。這種方式避免了頻繁建立UDF,能夠像使用Java調用同樣方便。

外表

問題場景:MaxCompute用戶的數據存儲在其餘存儲系統上,如HDFS,而且格式是CSV格式,有辦法使用SQL來操做嗎?

外表解決方案:MaxCompute中的外表功能支持用戶使用SQL來訪問其餘數據源和其餘數據格式的數據。下圖舉了一個例子,處理存儲在 OSS上的CSV文件。首先須要定義一個外表,定義命令中須要指定csv讀取的schema,MaxCompute內置csv文件的handler以及要處理的css的位置;外表定義好以後就能夠直接對數據進行讀取,抽取的數據能夠直接參與SQL運算(和普通的SQL無異),無縫鏈接。

外表功能支持多種數據源和數據格式,同時支持用戶自定義的數據格式(以下圖所示)。

4、MaxCompute後續計劃

在介紹MaxCompute後續計劃以前,首先總結一下其相對於Hive的優點:

  • TPCH上有1倍以上的性能提高
  • SQL標準支持更好:Hive在跑TPC-DS這個benchmark的時候,有不少SQL是不支持的,而MaxCompute能夠作到100%支持;
  • 更好的編譯器:支持一次性報告錯誤,高效的錯誤恢復,支持warning;
  • Runtime硬基礎好:基於CPP實現的runtime,能夠達到更高效率
  • 更好的IDE支持:MaxCompute Studio
  • 對小做業支持更好:經過Service Mode支持,對於小做業能夠作到秒級甚至毫秒級的查詢;
  • 支持更多好用的語法:包括VALUES表達式、SCALAR SUBQUERIES、INTERSECT / MINUS、PYTHON UDF、UDT / UDJ、腳本模式和參數化視圖。

在後續版本中,MaxCompute將主要增長兩部分的新功能:

  • 內存計算:支持數據緩存在內存中,一次加載數據屢次使用,極大減小運行時間;
  • 更強大的腳本語言功能:好比支持在SQL中使用條件語句IF/ELSE,以及循環語句 LOOP。

5、我的成長經歷及經驗

從校招15年進入到阿里巴巴MaxCompute團隊,見證了MaxCompute從1.0到2.0的發展,我的經驗上來說,從學校來到阿里巴巴至關於從一個校園來到另外一個「校園」。團隊自己基於開源社區項目Apache Calcite項目,同時也是其深度用戶。使用過程當中,團隊將一些好的想法貢獻給社區,社區也積極接納,於是成爲committer是水到渠成的事情。

最先接觸開源社區是在兩年前,說到我的經驗,總結起來主要有兩點:
1)成長是按部就班的,一開始可能承擔的是很小的需求實現,經過積極地和社區交流學習,按部就班,承擔的需求會愈來愈大,貢獻也會逐漸增多;
2)從開源社區能夠學到不少東西,開源社區比較注重代碼質量和社區成員之間的溝通交流,經過及時的溝通交流會提早避免不少沒必要要的衝突和返工。



本文做者:晉恆

原文連接

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索