MaxCompute湖倉(cāng)一體方案新能力
一、增量更新和處理架構(gòu)
1、設(shè)計(jì)增量更新架構(gòu)的背景
當(dāng)前數(shù)據(jù)業(yè)務(wù)場(chǎng)景日趨復(fù)雜, 對(duì)于時(shí)效性要求低的單一全量數(shù)據(jù)處理場(chǎng)景,MaxCompute可以較好地滿足需求。時(shí)效性要求很高的秒級(jí)實(shí)時(shí)數(shù)據(jù)處理或者流處理,需要使用實(shí)時(shí)系統(tǒng)、流系統(tǒng)來(lái)滿足需求。
但對(duì)于大部份業(yè)務(wù)場(chǎng)景,通常并不要求秒級(jí)數(shù)據(jù)更新可見(jiàn),更多的是分鐘級(jí)或者小時(shí)級(jí)的增量數(shù)據(jù)處理場(chǎng)景,同時(shí)也會(huì)有海量數(shù)據(jù)的批處理場(chǎng)景。
對(duì)于此類業(yè)務(wù)場(chǎng)景,使用單一引擎或聯(lián)邦多引擎都會(huì)存在一些劣勢(shì)。如圖所示,如果使用單一的 MaxCompute 離線批量處理鏈路,分鐘級(jí)的數(shù)據(jù)和全量數(shù)據(jù)做處理和存儲(chǔ),會(huì)存在冗余的計(jì)算和存儲(chǔ)成本,時(shí)效性也不能較好地得到滿足。但如果單純使用實(shí)時(shí)系統(tǒng),資源消耗成本比較高,性價(jià)比較低,在處理大規(guī)模批處理時(shí)穩(wěn)定性也不足。
因此,一般綜合解決方案會(huì)采用Lambda架構(gòu)去支持大數(shù)據(jù)的復(fù)雜業(yè)務(wù),全量批處理使用 MaxCompute 鏈路,時(shí)效性要求高的使用增量處理實(shí)時(shí)鏈路。但該架構(gòu)也存在大家所熟知的問(wèn)題,如圖中所示。
2、MaxCompute近實(shí)時(shí)增量更新和處理一體化業(yè)務(wù)架構(gòu)實(shí)踐
如圖所示,對(duì)于各種數(shù)據(jù)源,我們提供豐富的數(shù)據(jù)源接入工具,來(lái)支持近實(shí)時(shí)的增量導(dǎo)入和離線批量數(shù)據(jù)的導(dǎo)入,內(nèi)部使用統(tǒng)一的數(shù)據(jù)存儲(chǔ)和優(yōu)化服務(wù)管理數(shù)據(jù),統(tǒng)一的計(jì)算引擎支持近實(shí)時(shí)增量處理鏈路和大規(guī)模離線批處理的整體鏈路,統(tǒng)一的元數(shù)據(jù)服務(wù)支撐事務(wù)和文件的元數(shù)據(jù)管理。該一體化整體架構(gòu)優(yōu)勢(shì)顯著,可解決Lambda的一系列問(wèn)題,如節(jié)省了冗余的數(shù)據(jù)存儲(chǔ)成本以及不同系統(tǒng)間的數(shù)據(jù)遷移成本,消除了多套系統(tǒng)處理差異導(dǎo)致的數(shù)據(jù)不一致問(wèn)題,相對(duì)于單獨(dú)使用實(shí)時(shí)/流處理的方式,性價(jià)比更高;并且既可以滿足增量處理鏈路的時(shí)效性,也能滿足批處理的高效性。
此外,該套架構(gòu)還提供了upsert、timetravel等一系列實(shí)用的功能,擴(kuò)展整體的業(yè)務(wù)場(chǎng)景,節(jié)省用戶的資源成本,并提升用戶體驗(yàn)。
3、MaxCompute近實(shí)時(shí)增量更新和處理整體技術(shù)架構(gòu)
如圖所示為MaxCompute近實(shí)時(shí)增量更新和處理的整體技術(shù)架構(gòu),主要分為五個(gè)模塊進(jìn)行改造,包括數(shù)據(jù)接入、計(jì)算引擎、數(shù)據(jù)優(yōu)化服務(wù),元數(shù)據(jù)管理,數(shù)據(jù)文件組織層;其它部分可直接復(fù)用 MaxCompute 已有的技術(shù)架構(gòu)和實(shí)現(xiàn)。
- 數(shù)據(jù)接入層,主要支持各種數(shù)據(jù)源全量和近實(shí)時(shí)增量導(dǎo)入功能。結(jié)合多種數(shù)據(jù)導(dǎo)入產(chǎn)品定制開(kāi)發(fā)支持了豐富的數(shù)據(jù)導(dǎo)入方式,并且改造完善了MaxCompute高效的數(shù)據(jù)通道服務(wù)(內(nèi)部稱為Tunnel),支持全量和近實(shí)時(shí)增量的高效導(dǎo)入。
- 計(jì)算引擎層主要包含MC自研的SQL引擎以及其它第三方引擎,負(fù)責(zé) Timetravel 和增量場(chǎng)景下的SQL全鏈路處理和優(yōu)化。
- 數(shù)據(jù)優(yōu)化服務(wù)主要由 MaxCompute內(nèi)部的Storage Service ,負(fù)責(zé)智能自動(dòng)管理增量數(shù)據(jù)文件,其中包括小文件合并 Clustering,數(shù)據(jù)文件的Compaction,數(shù)據(jù)排序等優(yōu)化服務(wù)。
- 元數(shù)據(jù)服務(wù),主要負(fù)責(zé)增量場(chǎng)景下并發(fā)事務(wù)的沖突管理、數(shù)據(jù)版本管理,Timetravel 管理、數(shù)據(jù)文件元數(shù)據(jù)管理等。
- 數(shù)據(jù)文件組織主要包含F(xiàn)ile Format以及Table Format,主要包含對(duì)全量和增量數(shù)據(jù)文件格式的管理以及讀寫相關(guān)的模塊。
4、Transactional Table 2.0(事務(wù)表2.0)
為了支持增量更新,我們?cè)O(shè)計(jì)了一種新的表類型-Transactional Table 2.0 (簡(jiǎn)稱TT2)。對(duì)于建表操作只需在普通表基礎(chǔ)上額外設(shè)置主鍵primary key (PK),以及表屬性 Transactional 為 true 即可,無(wú)需其他額外配置。
其中,PK用于支持 upsert功能, PK值相同的多行記錄最終會(huì) merge合并成一行,以滿足主鍵唯一性的約束;Transactional表屬性表示支持 ACID屬性及事務(wù)機(jī)制。
如圖所示,TT2支持多種數(shù)據(jù)文件格式,主要支持Base File和Delta File。Delta File表示每次事務(wù)寫入的增量數(shù)據(jù)文件,會(huì)保持每一行數(shù)據(jù)的中間狀態(tài),用于滿足近實(shí)時(shí)的增量查詢需求;Base File是由Delta File進(jìn)行Compaction合并生成,不會(huì)保留中間狀態(tài),采用了列式壓縮存儲(chǔ)的格式,用戶支持高效的全量數(shù)據(jù)查詢場(chǎng)景。
為了進(jìn)一步優(yōu)化讀寫效率,TT2支持按照Bucket Index 對(duì)數(shù)據(jù)進(jìn)行分桶存儲(chǔ),bucket 數(shù)量可通過(guò)配置表屬性write.bucket.num指定;分桶后,大部分?jǐn)?shù)據(jù)操作如數(shù)據(jù)寫入、重排、優(yōu)化等,可以按照bucket粒度進(jìn)行并發(fā)處理,如果對(duì)bucket數(shù)據(jù)列查詢過(guò)濾,可進(jìn)行Bucket級(jí)別裁剪優(yōu)化,提升查詢的效率。
5、近實(shí)時(shí)增量寫入
下面將會(huì)介紹如何將數(shù)據(jù)寫入TT2表,主要分為批量寫入和近實(shí)時(shí)寫入;這里先描述如何設(shè)計(jì)高并發(fā)的近實(shí)時(shí)增量寫入場(chǎng)景。
我們定制開(kāi)發(fā)了 Flink Connector,以及Dataworks 數(shù)據(jù)集成及其他工具,都可以實(shí)現(xiàn)數(shù)據(jù)的增量寫入,這些工具內(nèi)部會(huì)調(diào)用MaxCompute的Tunnel通道服務(wù)提供的客戶端SDK,數(shù)據(jù)便可以以分鐘級(jí)并發(fā)寫入存儲(chǔ)。
數(shù)據(jù)寫入接口,目前僅支持upsert和delete兩種格式,未來(lái)會(huì)進(jìn)行擴(kuò)展;upsert 包含 insert/update 兩種隱含語(yǔ)義,如數(shù)據(jù)行不存在就代表 insert,如已存在就代表 update。commit 接口代表原子提交這段時(shí)間寫入的數(shù)據(jù),如返回成功,則寫入數(shù)據(jù)查詢可見(jiàn);如返回失敗,則數(shù)據(jù)不可見(jiàn),數(shù)據(jù)需要重寫或重試。該操作滿足Read Commit隔離級(jí)別。
6、批量寫入
下面將介紹批量寫入。批量導(dǎo)入主要通過(guò) SQL 進(jìn)行操作。為了方便用戶操作,我們實(shí)現(xiàn)了整套的DML語(yǔ)法。SQL 引擎內(nèi)核模塊包括 Compiler、Optimizer、Runtime 等都做了大量改造開(kāi)發(fā)來(lái)支持新架構(gòu)的功能,如針對(duì) pk 列的去重操作,runtime 構(gòu)造 upsert 格式數(shù)據(jù)的寫入,以及并發(fā)寫入等等。此處還涉及到DML操作過(guò)程中,Meta服務(wù)需要完整的事務(wù)機(jī)制來(lái)保證讀寫隔離、事務(wù)沖突檢測(cè)等操作。
7、數(shù)據(jù)組織優(yōu)化服務(wù)
由于TT2事務(wù)表需要支持分鐘級(jí)近實(shí)時(shí)增量數(shù)據(jù)導(dǎo)入,有可能會(huì)產(chǎn)生大量小文件,導(dǎo)致存儲(chǔ)訪問(wèn)壓力大、數(shù)據(jù)讀寫 IO 效率低、分析效率低等問(wèn)題。因此,我們開(kāi)發(fā)了Clustering服務(wù)來(lái)解決小文件合并的問(wèn)題,該服務(wù)由之前提到的Storage Service來(lái)執(zhí)行。
由左圖所示可以了解Clustering 服務(wù)的整體操作過(guò)程。在t1到t9的時(shí)間段,可見(jiàn)產(chǎn)生了大量的delta文件,Clustering會(huì)周期性地分析數(shù)據(jù)文件情況,如果滿足觸發(fā)條件,就會(huì)以Bucket為粒度,并發(fā)地執(zhí)行合并操作,為了滿足不同業(yè)務(wù)場(chǎng)景的需求,合并的策略比較豐富,比如根據(jù)文件大小、數(shù)量、時(shí)序相關(guān)的多個(gè)維度,并按照不同層次進(jìn)行合并,此外,對(duì)于超過(guò)一定大小的文件,做了一些優(yōu)化,不會(huì)對(duì)其進(jìn)行合并。
TT2還會(huì)寫入upsert和delete格式的數(shù)據(jù),可能會(huì)造成中間狀態(tài)的冗余記錄比較多,計(jì)算成本高且處理效率低下,因此我們?cè)O(shè)計(jì)了Compaction操作,對(duì)所有記錄進(jìn)行merge合并,消除上述中間狀態(tài)。Compaction操作由Storage Service負(fù)責(zé)執(zhí)行,即支持手動(dòng)觸發(fā),也可以按照時(shí)間頻率自動(dòng)觸發(fā)。
結(jié)合上圖可大概了解 Compaction 服務(wù)的整體操作流程。t1 到 t3 時(shí)間段,一些 delta files 寫入進(jìn)來(lái),觸發(fā) compaction 操作,同樣會(huì)以 bucket 粒度并發(fā)執(zhí)行,把所有的 delta files 進(jìn)行 merge,然后生成新的 base file。之后 t4 和 t6 時(shí)間段,又寫入了一批新的 delta files,再觸發(fā) compaction 操作,會(huì)把當(dāng)前存在的 base file 和新增的 delta files 一起做 merge 操作,重新生成一個(gè)新的 base file。該過(guò)程會(huì)迭代進(jìn)行,因此base文件可以實(shí)現(xiàn)加速全量快照查詢的目的。
8、Timetravel和增量查詢
此處Timetravel 查詢,主要用來(lái)查詢歷史版本的數(shù)據(jù),主要用于有數(shù)據(jù)歷史狀態(tài)回溯需求的業(yè)務(wù)場(chǎng)景,或數(shù)據(jù)出錯(cuò)時(shí)恢復(fù)歷史狀態(tài)數(shù)據(jù)進(jìn)行數(shù)據(jù)校驗(yàn)等。
通過(guò)一個(gè)簡(jiǎn)單的case進(jìn)行講解,例如上面創(chuàng)建了一張表,包含一些pk 列和val 列。左邊圖展示了數(shù)據(jù)變化過(guò)程,在 t2 和 t4 時(shí)刻分別執(zhí)行了compaction操作,生成了兩個(gè)base文件: b1和b2。
在t1時(shí)刻,只需讀取 delta file (d1) 進(jìn)行輸出;如果用戶查詢 t2 時(shí)刻,當(dāng)時(shí)通過(guò)Compaction生成了b1這個(gè)base文件,只需讀取 base文件并輸出對(duì)應(yīng)記錄即可。base文件會(huì)對(duì)d1和d2兩個(gè)文件合并,生成了三條記錄,消除了2a這個(gè)中間記錄。如查詢 t3 時(shí)刻,就會(huì)包含 base file ( b1) 加上 delta file (d3) 進(jìn)行Merge合并輸出,后續(xù)時(shí)刻的查詢過(guò)程同上,不再贅述。
因此可以看出,Timetravel會(huì)找到要查詢的歷史版本前最新的base文件,以及后續(xù)的delta文件,一起進(jìn)行Merge輸出。對(duì)于base文件主要用于提高查詢效率,用戶可以根據(jù)自己的業(yè)務(wù)場(chǎng)景選擇合適的頻率進(jìn)行Compaction操作。由于Compaction操作本身也會(huì)占用一定的存儲(chǔ)和計(jì)算,因此不能盲目頻繁地執(zhí)行。
下面的表格是一個(gè)增量查詢的場(chǎng)景,主要用于業(yè)務(wù)的近實(shí)時(shí)增量處理鏈路。查詢的時(shí)間范圍是一個(gè)左開(kāi)右閉的區(qū)間,即 begin 是一個(gè)開(kāi)區(qū)間,必須大于它,end 是一個(gè)閉區(qū)間。
如 begin 是 t1-1,end 是 t1,只讀取 t1 時(shí)間段對(duì)應(yīng)的 delta file (d1) 進(jìn)行輸出,如果 end 是 t2,會(huì)讀取兩個(gè) delta files (d1 和 d2);如果 begin 是 t1,end 是 t5,即查詢的時(shí)間范圍為 [t2, t5],會(huì)查詢所有的delta文件,即d2,d3,d4,d5,進(jìn)行合并輸出。這便是增量查詢和Timetravel查詢的區(qū)別。
此外,增量查詢對(duì)一些專門的場(chǎng)景進(jìn)行優(yōu)化,例如Clustering合并小文件,從語(yǔ)義上對(duì)已有數(shù)據(jù)記錄進(jìn)行合并,因此增量查詢時(shí)不會(huì)作為新增的數(shù)據(jù)查詢出來(lái)。
9、特點(diǎn)總結(jié)
作為一個(gè)新設(shè)計(jì)的架構(gòu),MaxCompute 會(huì)盡量去覆蓋HUDI / Iceberg + Spark/Presto整體數(shù)據(jù)湖解決方案的業(yè)務(wù)場(chǎng)景,有助于有類似業(yè)務(wù)需求的用戶進(jìn)行數(shù)據(jù)和業(yè)務(wù)鏈路遷移。此外,MaxCompute 離線近實(shí)時(shí)增量處理一體化架構(gòu)還具備一些獨(dú)特的亮點(diǎn):
- 統(tǒng)一的存儲(chǔ)、元數(shù)據(jù)、計(jì)算引擎一體化設(shè)計(jì),做了非常深度和高效的集成,具備存儲(chǔ)成本低,數(shù)據(jù)文件管理高效,查詢效率高。
- 全套統(tǒng)一的 SQL 語(yǔ)法支持,非常便于用戶使用。
- 深度定制優(yōu)化的數(shù)據(jù)導(dǎo)入工具,支持一些復(fù)雜的業(yè)務(wù)場(chǎng)景。
- 無(wú)縫銜接 MaxCompute 現(xiàn)有的業(yè)務(wù)場(chǎng)景,可以減少遷移、存儲(chǔ)、計(jì)算成本。
- 完全自動(dòng)化管理數(shù)據(jù)文件,保證更好的讀寫穩(wěn)定性和性能,自動(dòng)優(yōu)化存儲(chǔ)效率和成本。
- 基于 MaxCompute 平臺(tái)完全托管,用戶可以開(kāi)箱即用。
二、智能物化視圖
1、智能物化視圖演進(jìn)
使用過(guò)SQL的人基本都對(duì)物化視圖有大概了解,其實(shí)就是將邏輯視圖的結(jié)果物化下來(lái),本質(zhì)上就是存儲(chǔ)數(shù)據(jù)的物理表。其作用主要是把耗時(shí)操作的計(jì)算結(jié)果保存下來(lái),避免重復(fù)計(jì)算,從而達(dá)到整體的查詢加速的目的。MaxCompute的物化視圖也經(jīng)歷了一系列的演進(jìn)過(guò)程。一開(kāi)始我們就支持了比較豐富的SQL語(yǔ)法功能,比如聚簇,分區(qū)等。
對(duì)于分區(qū)物化視圖,類似于分區(qū)表,數(shù)據(jù)是通過(guò)分區(qū)的粒度進(jìn)行存儲(chǔ)和管理的。在實(shí)際場(chǎng)景中,物化視圖的分區(qū)和源表的分區(qū)不一定保持一致,例如源表增加新的分區(qū),物化視圖可能還沒(méi)來(lái)得及更新,或者只更新部分分區(qū)的場(chǎng)景。如果用戶要查詢指定的分區(qū),但物化視圖只存了部分歷史分區(qū)數(shù)據(jù),MaxCompute支持了分區(qū)穿透的功能來(lái)優(yōu)化此場(chǎng)景的查詢。對(duì)于物化視圖存在的分區(qū),可以從物化視圖中查詢,對(duì)于物化視圖不存在的分區(qū),直接從源表中穿透讀取。這樣就可以利用物化視圖的結(jié)果,還能保證結(jié)果和源表一致。
此外最普遍的場(chǎng)景就是計(jì)算邏輯和物化視圖表達(dá)式計(jì)算邏輯相似,語(yǔ)義的輸出結(jié)果是物化視圖的子集。為了充分利用好物化視圖的結(jié)果,支持在物化視圖的數(shù)據(jù)集上,對(duì)數(shù)據(jù)進(jìn)一步加工,獲得用戶查詢的結(jié)果。例如查找值大于10的數(shù)據(jù) ,在改寫后便可以直接從物化視圖中直接增加一個(gè)過(guò)濾條件>10,便可以搜索出大于10的結(jié)果,避免了查詢?cè)幢砣繑?shù)據(jù)的過(guò)程,查詢改寫功能可有效提升查詢性能,降低資源消耗。對(duì)于圖中展示的查詢改寫例子比較簡(jiǎn)單,MaxCompute已支持非常豐富的復(fù)雜操作,比如aggregate、join等,只要表達(dá)式等效,或查詢的結(jié)果集是物化視圖的子集,能夠轉(zhuǎn)換成對(duì)應(yīng)的表達(dá)式,都可以進(jìn)行改寫。
由于源表和物化視圖的數(shù)據(jù)存儲(chǔ)在不同地方。當(dāng)源表發(fā)生更新,但物化視圖沒(méi)有更新時(shí),SQL查詢無(wú)法利用物化視圖的結(jié)果。需要整體回退,查詢?cè)幢怼榱烁玫靥岣卟樵冃剩覀冊(cè)谡Z(yǔ)法上支持定時(shí)觸發(fā)操作,在一定的時(shí)間范圍內(nèi)保證物化視圖和源表數(shù)據(jù)基本保持一致。
2、物化視圖智能推薦機(jī)制
為了使用物化視圖,用戶需要非常了解物化視圖的概念,運(yùn)行原理,以及業(yè)務(wù)情況,才能達(dá)到較好的使用效果。但很多場(chǎng)景中,公司業(yè)務(wù)較為復(fù)雜,個(gè)人無(wú)法從全局了解公司的業(yè)務(wù)情況,因此無(wú)法從查詢最優(yōu)的角度來(lái)創(chuàng)建高效的物化視圖。此外,用戶對(duì)于創(chuàng)建物化視圖前后的資源消耗情況,也難以評(píng)估。
為了加大物化視圖的使用場(chǎng)景和推廣,降低整體物化視圖的使用門檻,MaxCompute引擎支持自動(dòng)化地分析用戶業(yè)務(wù)歷史作業(yè)的運(yùn)行情況,根據(jù)合理的策略篩選出效果比較好的物化視圖,上圖為簡(jiǎn)單的智能物化視圖機(jī)制的運(yùn)行原理。首先,引擎會(huì)對(duì)所有作業(yè)進(jìn)行分析,抽取出所有符合要求的子表達(dá)式, 實(shí)際策略上會(huì)盡可能選擇包含aggregate和join的子表達(dá)式做物化視圖,最終查詢優(yōu)化的整體效果會(huì)更好。
其次,會(huì)對(duì)所有符合要求的子表達(dá)式進(jìn)行格式統(tǒng)一的歸一化處理。例如將所有算子的順序進(jìn)行排布整理等,隨后會(huì)對(duì)歸一化符合要求的子表達(dá)式進(jìn)行合并,生成一些新的公共表達(dá)式,從而擴(kuò)展應(yīng)用場(chǎng)景。
最后,對(duì)所有篩選生成的表達(dá)式的執(zhí)行效果進(jìn)行評(píng)估,給出哪些表達(dá)式適合作為物化視圖的候選。此處需要獲取物化視圖計(jì)算時(shí)需要的CPU、內(nèi)存、存儲(chǔ)等信息,從而做出相對(duì)準(zhǔn)確的對(duì)比評(píng)估。
最后,會(huì)根據(jù)公共表達(dá)式的使用頻率和執(zhí)行占用的資源效果,整體評(píng)估物化視圖優(yōu)化應(yīng)用的效果,按順序展現(xiàn)給所有用戶候選的公共表達(dá)式列表,因此即使是小白用戶,也可以無(wú)腦的選擇推薦排名靠前的物化視圖進(jìn)行使用和驗(yàn)證,可大大減少資源消耗,同時(shí)可以提高用戶的業(yè)務(wù)性能。
該功能在MaxCompute公共云已經(jīng)上線,效果非常好,預(yù)計(jì)可以節(jié)省14%的CU資源。
三、Adaptive執(zhí)行優(yōu)化
1、SQL引擎多層次Adaptive執(zhí)行
對(duì)比Spark到3.0版本才支持Adaptive執(zhí)行框架,MaxCompute的SQL引擎一開(kāi)始的定位就是多層次和多維度的動(dòng)態(tài)Adaptive執(zhí)行計(jì)算優(yōu)化。
以圖中所述的執(zhí)行聚合聚合操作的SQL為例,SQL Optimizer模塊會(huì)根據(jù)Compiler解析的SQL語(yǔ)法樹(shù),根據(jù)靜態(tài)的Table或者分區(qū)級(jí)別的Stats信息結(jié)合RBO/CBO/HBO計(jì)算出執(zhí)行代價(jià)較低的執(zhí)行Plan,提交給Job Master執(zhí)行,調(diào)度Runtime Worker進(jìn)行數(shù)據(jù)計(jì)算處理。Runtime內(nèi)部也會(huì)根據(jù)上游Worker的輸入數(shù)據(jù)Stats進(jìn)行Plan優(yōu)化調(diào)整,此外,運(yùn)行中的算子會(huì)根據(jù)實(shí)時(shí)流入的數(shù)據(jù)特征,動(dòng)態(tài)切換最合適的算法進(jìn)行計(jì)算。
同時(shí),Job Master也會(huì)不斷收集operator、work級(jí)別統(tǒng)計(jì)的數(shù)據(jù)Stats,回傳給Job Master做一些匯總和分析,進(jìn)一步做Stage級(jí)別的動(dòng)態(tài)優(yōu)化調(diào)整,比如并發(fā)度的調(diào)整等。
此外,在運(yùn)行時(shí),Job Master還會(huì)把Stage級(jí)別的數(shù)據(jù)Stats回傳給Optimizer,它會(huì)根據(jù)這些實(shí)時(shí)Stats對(duì)還未執(zhí)行的Plan重新進(jìn)行優(yōu)化,然后把新的Job Plan再次提交給Job Master繼續(xù)執(zhí)行。
由上述流程可知,MaxCompute的SQL引擎可以自適應(yīng)地根據(jù)多維度的Stats執(zhí)行多層次的Adaptive優(yōu)化,這可以充分發(fā)揮和協(xié)調(diào)各個(gè)模塊的能力。后面將會(huì)簡(jiǎn)單介紹下對(duì)每個(gè)層次的優(yōu)化實(shí)踐。
2、SQL Plan DAG動(dòng)態(tài)調(diào)整
假如用戶執(zhí)行SQL: select * from t1 join t2 where t1.a=t2.b,上圖展示一種Plan級(jí)別DAG的動(dòng)態(tài)調(diào)整示例。對(duì)于Join的分布式實(shí)現(xiàn),主要分為Shuffle Join和Map Join兩種實(shí)現(xiàn),Shuffle Join如左側(cè)的Plan A所示,左右兩張表都要進(jìn)行一次Shuffle操作,主要用于左右表都很大的場(chǎng)景。對(duì)于右側(cè)Plan B,會(huì)把右表的所有記錄挪到左表的所有map實(shí)例中,避免了左表的Shuffle操作,適用于左右表一個(gè)很大一個(gè)很小的場(chǎng)景。
但優(yōu)化器在執(zhí)行的過(guò)程中,無(wú)法感知右表的大小,所以無(wú)法事先決定采用哪種join實(shí)現(xiàn)。針對(duì)這種場(chǎng)景,我們同時(shí)生成plan A和plan B兩種計(jì)劃,并把它們同時(shí)傳給Job Master,Job Master會(huì)先執(zhí)行右表,獲取到右表的數(shù)據(jù)總size后,再?zèng)Q定采用plan A還是plan B,在Plan B生效的場(chǎng)景下,相對(duì)Plan A通常可極大節(jié)省大表的shuffle開(kāi)銷,提升幾倍的性能。
3、Stage動(dòng)態(tài)調(diào)整
下面介紹Stage級(jí)別的動(dòng)態(tài)調(diào)整的兩個(gè)場(chǎng)景。一個(gè)典型的場(chǎng)景就是Stage并發(fā)度的調(diào)整。當(dāng)上游Stage完成之后,會(huì)按照預(yù)先設(shè)置的并發(fā)度計(jì)算出下游實(shí)例應(yīng)該處理的數(shù)據(jù)量,如圖所示,便可以動(dòng)態(tài)調(diào)整并發(fā)數(shù)。size較小的實(shí)例可以進(jìn)行合并,size較大的實(shí)例可以進(jìn)行拆分,均勻分布每個(gè)新實(shí)例的處理量,從而避免長(zhǎng)尾和資源碰撞,使整體資源使用價(jià)值最大化。
另一個(gè)是Shuffle Join Worker動(dòng)態(tài)調(diào)整的場(chǎng)景。在運(yùn)行的過(guò)程中,如果發(fā)現(xiàn)有些表的數(shù)據(jù)實(shí)例發(fā)生嚴(yán)重傾斜,大概率會(huì)出現(xiàn)長(zhǎng)尾問(wèn)題,引擎會(huì)動(dòng)態(tài)將其拆分為n個(gè)實(shí)例, 比如圖中左表數(shù)據(jù)量為60這個(gè)實(shí)例,會(huì)被拆分成3個(gè)數(shù)據(jù)量20的實(shí)例并發(fā)執(zhí)行,另外一個(gè)實(shí)例會(huì)把數(shù)據(jù)broadcast分發(fā)到左表的三個(gè)實(shí)例中并發(fā)進(jìn)行Join操作,從而避免長(zhǎng)尾,縮短整體運(yùn)行時(shí)間。
4、Worker內(nèi)DAG動(dòng)態(tài)調(diào)整
下面將介紹Worker內(nèi)DAG執(zhí)行的動(dòng)態(tài)調(diào)整,如圖所示是一個(gè)Shuffle Join的實(shí)例。在開(kāi)始運(yùn)行時(shí),可以根據(jù)從上游Worker獲取到左右表實(shí)例的size來(lái)決定走Hash Join還是Merge Join,如果符合Hash Join的DAG執(zhí)行,就可以避免大表排序時(shí)發(fā)生大量的Spill落盤的操作,節(jié)省大量的IO資源,從而可以提升運(yùn)行速度。
5、Operator動(dòng)態(tài)執(zhí)行
最后,worker內(nèi)部的具體某個(gè)算子其實(shí)也可以動(dòng)態(tài)執(zhí)行。運(yùn)行時(shí)會(huì)根據(jù)實(shí)時(shí)數(shù)據(jù)特征來(lái)Adaptive選擇不同的算法進(jìn)行執(zhí)行。對(duì)于Partial Hash Aggregator,可以根據(jù)實(shí)時(shí)的聚合效果決定是否持續(xù)進(jìn)行聚合;對(duì)于排序可以先拿一些數(shù)據(jù)樣本做一下預(yù)排序,根據(jù)排序效果決定采用哪種排序處理后續(xù)的數(shù)據(jù);壓縮方面,也可以根據(jù)壓縮效果決定是否壓縮等。
四、問(wèn)答部分
物化視圖和物理表有什么區(qū)別?
物化視圖本質(zhì)上可以理解為也是一張物理表,只不過(guò)多了一個(gè)源表的關(guān)聯(lián)信息,源表更新時(shí),物化視圖需要同步更新。另外,物化視圖支持智能推薦,也可用于預(yù)計(jì)算的cache,用戶無(wú)需感知物化視圖存在,在查詢SQL時(shí),如果對(duì)部分計(jì)算做了cache,可以直接從cache中讀取數(shù)據(jù),來(lái)避免重復(fù)耗時(shí)的計(jì)算,在具體存儲(chǔ)上二者并沒(méi)有太大的區(qū)別。
物化視圖有沒(méi)有設(shè)置過(guò)期時(shí)間的考慮?
物化視圖會(huì)有一個(gè)生命周期,超過(guò)生命周期,物化視圖也會(huì)被刪除。
Hash Join和Merge Join有什么優(yōu)劣,實(shí)際場(chǎng)景應(yīng)該如何選擇?
這其實(shí)是分布式中的一個(gè)典型場(chǎng)景,對(duì)于Hash Join在具體實(shí)現(xiàn)上其實(shí)分兩種,一種是我們說(shuō)的Map Join,Map Join會(huì)把小表全部廣播到大表側(cè)的每一個(gè)實(shí)例上,這樣大表側(cè)就無(wú)需做數(shù)據(jù)分布,可以直接從源表中讀出一部分?jǐn)?shù)據(jù),跟broadcast過(guò)來(lái)的小表做一個(gè)Hash join進(jìn)行輸出即可,這樣可以避免大表側(cè)的shuffle數(shù)據(jù)重排操作。
Hash Join還有另外一種場(chǎng)景,也就是Shuffle Join,就是大表和小表同時(shí)做shuffle。在每個(gè)具體實(shí)例上,數(shù)據(jù)可以選擇走Hash Join,還是走M(jìn)erge Join,二者是存在算法上的不同。Hash Join是選擇一個(gè)小表構(gòu)建Hash表,大表會(huì)直接通過(guò)lookup進(jìn)行輸出,不涉及任何排序操作,只要內(nèi)存中能放下小表即可,效率比較高。對(duì)于Merge Join,左右兩張表都比較大的場(chǎng)景,無(wú)法從內(nèi)存中放下一個(gè)Hash表,可以對(duì)左右表的數(shù)據(jù)進(jìn)行排序,排序完的數(shù)據(jù)通過(guò)有序的join就無(wú)需通過(guò)Hash方式,而是可以在內(nèi)存中通過(guò)流式的方式去判斷兩個(gè)group是否為同一個(gè)key即可。
此外,還有一種場(chǎng)景,就是左右兩邊的數(shù)據(jù)本來(lái)就是有序的,比如一些Cluster表的數(shù)據(jù)。這樣可以直接應(yīng)用Merge Join,效果也會(huì)更高。所以本質(zhì)上一是跟左右表的大小相關(guān),另外也跟算法的效率相關(guān)。