Flink Table API/SQL 是如何變成程序運(yùn)行的
本文轉(zhuǎn)載自微信公眾號(hào)「KK架構(gòu)師」,作者wangkai。轉(zhuǎn)載本文請(qǐng)聯(lián)系KK架構(gòu)師公眾號(hào)。
一、Flink Api 的分層抽象
如上圖,最下面一層是 Process Function ,可以去做一些有狀態(tài)的計(jì)算,注冊(cè) Timer 定時(shí)器,可以做更復(fù)雜的操作,靈活性更高,可以做非常復(fù)雜的定制開(kāi)發(fā);
第二層是 DataStream Api,基于 Process Function,封裝了很多的操作。比如可以方便做一個(gè) KeyBy 操作 + Window 的聚合;
最上面一層是 關(guān)系型 Api,是在 DataStream Api 之上的更高級(jí)的抽象,我們可以借助 SQL 這種非常經(jīng)典的穩(wěn)定的語(yǔ)言,來(lái)構(gòu)建實(shí)時(shí)流程序。
二、為什么要提供 Table Api 和 SQL?
1. 開(kāi)發(fā)繁瑣
DataStream Api / Process Function 更加面向的是開(kāi)發(fā)者,想要開(kāi)發(fā)出合理的 Flink 程序,至少需要具備以下技能:
- 具有 Java 、Scala 開(kāi)發(fā)經(jīng)驗(yàn);
- 需要對(duì) Time、State 以及 Window 等流式概念有非常深入的了解;
- 具有分布式處理的經(jīng)驗(yàn)和知識(shí);
- 具有作業(yè)調(diào)優(yōu)的經(jīng)驗(yàn);
這樣的話(huà),對(duì)數(shù)據(jù)分析人員和業(yè)務(wù)人員很不友好,使用起來(lái)學(xué)習(xí)成本非常高,望塵莫及。
并且開(kāi)發(fā)起來(lái)非常繁瑣,開(kāi)發(fā)應(yīng)用需要使用 Function 接口,即使是一個(gè)簡(jiǎn)單的過(guò)濾也要實(shí)現(xiàn)一個(gè) FilterFunction 匿名類(lèi),而使用 Table Api 則簡(jiǎn)單很多。
2. 代碼不通用
Table Api 和 SQL 是流批通用的,代碼完全可以復(fù)用。不必流式程序使用 DataStream Api,批處理使用 DataSet Api (注:社區(qū)未來(lái)可能會(huì)廢棄 Dataset Api,統(tǒng)一使用 DataStream Api 來(lái)開(kāi)發(fā)批流程序)。
3. 框架很難優(yōu)化
在使用 DataStream Api 和 DataSet Api 開(kāi)發(fā)應(yīng)用的時(shí)候,F(xiàn)link 框架只能進(jìn)行非常有限的優(yōu)化,需要開(kāi)發(fā)者非常謹(jǐn)慎的編寫(xiě)高效的應(yīng)用程序。
而使用 Table Api 或 SQL,則可以使用 Calcite 的 SQL 優(yōu)化器,更容易寫(xiě)出執(zhí)行效率高的應(yīng)用。
二、Table Api / SQL 是如何轉(zhuǎn)換為程序運(yùn)行的?
如下圖所示
SQL 執(zhí)行被分成兩個(gè)大的階段,從 SQL 語(yǔ)句到 Operation,從 Operation 到 Transformation,然后就進(jìn)入分布式執(zhí)行的階段。
1. 前置知識(shí):Apache Calcite
Apache Calcite 是個(gè)動(dòng)態(tài)數(shù)據(jù)管理框架,具備很多數(shù)據(jù)庫(kù)管理系統(tǒng)的功能,如 SQL 解析,SQL 校驗(yàn),SQL 查詢(xún)優(yōu)化,SQL 生成以及數(shù)據(jù)連接查詢(xún)等,但是并不存儲(chǔ)元數(shù)據(jù)和基本數(shù)據(jù),不包含處理數(shù)據(jù)的算法。
由于舍棄了這些功能,Calcite 可以在應(yīng)用和數(shù)據(jù)存儲(chǔ),數(shù)據(jù)處理引擎之間很好的扮演中介的角色。
它不受上層編程語(yǔ)言的限制,前端可以使用 SQL、Pig、Cascading 等語(yǔ)言,只要通過(guò) Calcite 提供的 SQL Api 將它們轉(zhuǎn)化成關(guān)系代數(shù)的抽象語(yǔ)法樹(shù)即可,并根據(jù)一定的規(guī)則和成本對(duì)抽象語(yǔ)法樹(shù)進(jìn)行優(yōu)化,最后推給各個(gè)數(shù)據(jù)處理引擎來(lái)執(zhí)行。
所以 Calcite 不涉及物理規(guī)劃層,它通過(guò)擴(kuò)展適配器來(lái)連接多種后端的數(shù)據(jù)源和數(shù)據(jù)處理引擎,如 Hive,Drill,F(xiàn)link,Phoenix。
2. SQL 語(yǔ)句到 Operation 過(guò)程
首先使用 Calcite 對(duì) SQL 語(yǔ)句進(jìn)行解析,獲取 SQL Node,再根據(jù)不同的 SQL 類(lèi)型分別進(jìn)行轉(zhuǎn)換,校驗(yàn)語(yǔ)法的合法性,再根據(jù)語(yǔ)句類(lèi)型(DQL、DML、DDL)轉(zhuǎn)換成對(duì)應(yīng)的算子樹(shù)。
對(duì)于 SQL 查詢(xún)語(yǔ)句而言,會(huì)轉(zhuǎn)換為 QueryOperation 樹(shù)。
3. Operation 到 Transformation 過(guò)程
首先 Operation 先轉(zhuǎn)換為 Calcite 的邏輯計(jì)劃樹(shù),再對(duì)應(yīng)地轉(zhuǎn)換為 Flink 的邏輯計(jì)劃樹(shù),然后進(jìn)行優(yōu)化。
優(yōu)化后的邏輯樹(shù)轉(zhuǎn)換為 Flink 的物理計(jì)劃,然后物理計(jì)劃通過(guò)代碼生成算子、UDF、表達(dá)式等代碼,包裝到 Transformation 中,形成 Transformation 流水線,再轉(zhuǎn)換為 StreamGraph ,最終就可以提交到 Flink 集群真正運(yùn)行起來(lái)了。
(后面會(huì)專(zhuān)門(mén)寫(xiě)源碼分析的文章,來(lái)重點(diǎn)講述這兩部分的內(nèi)容,持續(xù)關(guān)注我)
4. 元數(shù)據(jù)
元數(shù)據(jù)是是 Flink SQL 處理數(shù)據(jù)非常重要的一個(gè)部分,元數(shù)據(jù)描述了 Flink 處理的讀取和寫(xiě)出的數(shù)據(jù)的結(jié)構(gòu)以及數(shù)據(jù)的訪問(wèn)方法等信息,沒(méi)有元數(shù)據(jù),F(xiàn)link 就無(wú)法對(duì) SQL 進(jìn)行校驗(yàn)和優(yōu)化了。
元數(shù)據(jù)包含以下信息:
- 庫(kù)
- 表
- 視圖
- UDF
- 表字段
如上圖所示,在 Flink 中,Catalog 是元數(shù)據(jù)的核心抽象,目前 Flink 實(shí)現(xiàn)了內(nèi)存小 GenericMemoryCatalog 和 HiveCatalog 兩種 Catalog。
5. 優(yōu)化器
SQL 查詢(xún)優(yōu)化是來(lái)自數(shù)據(jù)庫(kù)系統(tǒng)的概念,查詢(xún)優(yōu)化器是關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)的核心之一,決定對(duì)特定的查詢(xún)使用哪些索引、哪些關(guān)聯(lián)算法,從而使 SQL 高效運(yùn)行。
SQL 優(yōu)化器很大程度上決定了一個(gè)系統(tǒng)的執(zhí)行性能。
查詢(xún)優(yōu)化器分成兩類(lèi),基于規(guī)則的優(yōu)化器(Rule-Based Optimizer,RBO)和基于代價(jià)的優(yōu)化器(Cost-Based Optimizer,CBO)。
RBO 規(guī)則優(yōu)化,主要就是等價(jià)改變查詢(xún)語(yǔ)句的形式,以便產(chǎn)生更好的邏輯執(zhí)行計(jì)劃,比如重寫(xiě)用戶(hù)的查詢(xún)(謂詞推進(jìn),物化視圖重寫(xiě),視圖合并等),然后還需要將邏輯執(zhí)行計(jì)劃變成物理執(zhí)行計(jì)劃。
CBO 代價(jià)優(yōu)化,除了做上述 RBO 的規(guī)則優(yōu)化外,還會(huì)通過(guò)復(fù)雜的算法統(tǒng)計(jì)信息,統(tǒng)計(jì)各個(gè)執(zhí)行計(jì)劃的執(zhí)行成本,從不同的執(zhí)行計(jì)劃中選擇出執(zhí)行代價(jià)最小的一個(gè)計(jì)劃,轉(zhuǎn)換為 Flink 的執(zhí)行計(jì)劃。
三、總結(jié)
Flink Table Api / SQL 提供了對(duì)用戶(hù)友好的接口來(lái)更高效的完成實(shí)時(shí)流式程序的開(kāi)發(fā)。
Flink 依托 Apache Calcite 提供的 SQL 解析、優(yōu)化框架,解析構(gòu)建為邏輯計(jì)劃樹(shù),通過(guò) Planner 層層優(yōu)化為 Flink 可以運(yùn)行的內(nèi)部結(jié)構(gòu),最終提交到 Flink 集群上運(yùn)行。