作者 | 士心先生
來(lái)源 | 程序員的讀書(shū)故事 (公眾號(hào):pg_reading)
查詢執(zhí)行模型
Presto通常部署為包含一個(gè)協(xié)調(diào)器和多個(gè)工作節(jié)點(diǎn)的集群痴奏。
在協(xié)調(diào)器內(nèi)部翎嫡,SQL語(yǔ)句首先以文本形式提交到協(xié)調(diào)器请敦,協(xié)調(diào)器解析和分析這條語(yǔ)句料祠,之后創(chuàng)建一個(gè)由Presto內(nèi)部數(shù)據(jù)結(jié)構(gòu)表示的執(zhí)行計(jì)劃秃嗜,叫做查詢計(jì)劃权均。
查詢計(jì)劃生成過(guò)程利用了元數(shù)據(jù)SPI和數(shù)據(jù)統(tǒng)計(jì)SPI來(lái)創(chuàng)建查詢計(jì)劃。也就是說(shuō)锅锨,協(xié)調(diào)器會(huì)使用SPI直接連接到數(shù)據(jù)源叽赊,以收集有關(guān)表和其他元數(shù)據(jù)的信息。
協(xié)調(diào)器通過(guò)元數(shù)據(jù)SPI獲取表必搞、列和數(shù)據(jù)類型的信息必指。這些信息用于對(duì)查詢進(jìn)行語(yǔ)義校驗(yàn)、類型檢查和安全檢查恕洲。
統(tǒng)計(jì)SPI用于獲取行數(shù)和表大小的信息塔橡,從而在計(jì)劃期間進(jìn)行基于代價(jià)的查詢優(yōu)化。
在創(chuàng)建分布式查詢計(jì)劃時(shí)會(huì)利用數(shù)據(jù)位置SPI來(lái)生成表內(nèi)容的邏輯切片霜第。切片是任務(wù)分配和并行的最小單位葛家。
分布式查詢計(jì)劃是簡(jiǎn)單查詢計(jì)劃的一個(gè)擴(kuò)展,它包含一個(gè)或多個(gè)stage泌类。簡(jiǎn)單查詢計(jì)劃被切分為多個(gè)計(jì)劃片段癞谒。Stage是在運(yùn)行時(shí)的計(jì)劃片段,它包含對(duì)應(yīng)計(jì)劃片段所描述的所有任務(wù)刃榨。
協(xié)調(diào)器將查詢計(jì)劃切分成Stage弹砚,從而分配給集群中的多個(gè)工作節(jié)點(diǎn)進(jìn)行并行處理,從而加快整體查詢的執(zhí)行速度喇澡。多個(gè)Stage會(huì)被組織成一棵依賴樹(shù)迅栅。Stage的數(shù)量依賴于查詢的復(fù)雜度。例如晴玖,查詢的表读存、返回的列、JOIN語(yǔ)句呕屎、Where條件让簿、Group by操作和其他SQL語(yǔ)句都可能影響Stage的數(shù)量。
分布式執(zhí)行計(jì)劃定義了Stage和查詢?cè)赑resto集群上執(zhí)行的方式秀睛。協(xié)調(diào)器使用它在工作節(jié)點(diǎn)上進(jìn)一步計(jì)劃和調(diào)度任務(wù)尔当。一個(gè)Stage通常包含一個(gè)或多個(gè)任務(wù),每個(gè)任務(wù)則負(fù)責(zé)處理一小部分?jǐn)?shù)據(jù)。
一個(gè)任務(wù)處理數(shù)據(jù)的單位是切片椭迎。切片代表一個(gè)工作節(jié)點(diǎn)可以抽取并處理的一段底層數(shù)據(jù)锐帜,它是并行和任務(wù)分配的單位。
源Stage的任務(wù)以page的形式生產(chǎn)數(shù)據(jù)畜号,每個(gè)page都是以列式存儲(chǔ)格式表示的一系列行缴阎。這些page傳輸?shù)较掠蔚闹虚gStage。Exchange算子從上游Stage中讀取數(shù)據(jù)简软,從而在不同Stage之間傳輸page蛮拔。
在連接器的幫助下,源任務(wù)使用數(shù)據(jù)源SPI從底層數(shù)據(jù)源獲取數(shù)據(jù)痹升。這些數(shù)據(jù)以
page的形式在Presto的查詢引擎之中傳送建炫。算子根據(jù)它們的語(yǔ)義處理接收到的page并產(chǎn)生新page。
包含在一個(gè)任務(wù)里的一串算子叫做流水線疼蛾。流水線中的最后一個(gè)算子通常會(huì)將它輸出的page放置在任務(wù)的輸出緩沖區(qū)中肛跌。下游任務(wù)的Exchange算子會(huì)從上游任務(wù)的輸出緩沖區(qū)中消費(fèi)page。所有這些操作都在不同的工作節(jié)點(diǎn)上并行運(yùn)行据过。
因此惋砂,任務(wù)是運(yùn)行時(shí)分配給一個(gè)工作節(jié)點(diǎn)的計(jì)劃片段。在任務(wù)創(chuàng)建之后绳锅,它會(huì)為每個(gè)切片初始化一個(gè)驅(qū)動(dòng)西饵。每個(gè)驅(qū)動(dòng)都是包含多個(gè)算子的流水線的一個(gè)實(shí)例,并且負(fù)責(zé)處理切片中的數(shù)據(jù)鳞芙。根據(jù)Presto配置和環(huán)境眷柔,一個(gè)任務(wù)可以使用一個(gè)或多個(gè)驅(qū)動(dòng)。當(dāng)所有驅(qū)動(dòng)都執(zhí)行完且數(shù)據(jù)被傳送到下一個(gè)切片時(shí)原朝,驅(qū)動(dòng)和任務(wù)的工作就結(jié)束了驯嘱,它們之后會(huì)被銷毀。
算子處理輸入數(shù)據(jù)并為下游算子生產(chǎn)輸出數(shù)據(jù)喳坠。常見(jiàn)的算子包括TableScan(表掃描)鞠评、Filter(過(guò)濾)、Join和Aggregate(聚合)壕鹉。一系列相連的算子組成一套算子流水線剃幌。例如,你可以擁有一條流水線晾浴,它先掃描并讀入數(shù)據(jù)负乡,再過(guò)濾數(shù)據(jù),最后在數(shù)據(jù)上執(zhí)行局部聚合脊凰。
要處理一條查詢抖棘,協(xié)調(diào)器首先根據(jù)來(lái)自連接器的元數(shù)據(jù)創(chuàng)建切片列標(biāo)。使用該切片列表,協(xié)調(diào)器開(kāi)始在工作節(jié)點(diǎn)上調(diào)度任務(wù)切省,以獲取其中的數(shù)據(jù)最岗。在查詢執(zhí)行期間,協(xié)調(diào)器跟蹤所有可用于處理的切片和任務(wù)在工作節(jié)點(diǎn)上執(zhí)行的位置数尿。一些任務(wù)完成了處理仑性,并產(chǎn)生了很多供下游處理的切片,協(xié)調(diào)器就會(huì)繼續(xù)調(diào)度更多的任務(wù)來(lái)處理它們右蹦,直到?jīng)]有待處理的切片為止。
一旦工作節(jié)點(diǎn)處理完了所有切片歼捐,全部數(shù)據(jù)就可用了何陆。此時(shí)協(xié)調(diào)器會(huì)將結(jié)果返回給客戶端。