天天看點

實時計算 Flink SQL 核心功能解密實時計算 Flink SQL 核心功能解密

Flink SQL 是于2017年7月開始面向集團開放流計算服務的。雖然是一個非常年輕的産品,但是到雙11期間已經支撐了數千個作業,在雙11期間,Blink 作業的處理峰值達到了5+億每秒,而其中僅 Flink SQL 作業的處理總峰值就達到了3億/秒。Flink SQL 在這麼短的時間内支撐了如此多的業務,與其穩定的核心、完善的功能、強大的生态是分不開的。

本文會帶着大家一起來揭開 Flink SQL 核心功能的面紗(API上我們将盡可能的和Flink社群保持一緻,這樣才能夠更好的融入開源的生态,是以我們将API叫做Flink SQL,而不是Blink SQL。事實上flink社群的SQL絕大部分是我們阿裡的工程師貢獻的:3個 Flink Committer,10+ Contributor,貢獻 80% 的SQL 功能,近200個 commit,近十萬行的代碼)。

Blink 将 SQL 定位為其最核心的 API。為什麼是 SQL 而不是 DataStream API 呢?因為 SQL 具有以下幾個優點:

實時計算 Flink SQL 核心功能解密實時計算 Flink SQL 核心功能解密

聲明式。使用者隻需要表達我想要什麼,至于怎麼計算那是系統的事情,使用者不用關心。

自動調優。查詢優化器可以為使用者的 SQL 生成最有的執行計劃。使用者不需要了解它,就能自動享受優化器帶來的性能提升。

易于了解。很多不同行業不同領域的人都懂 SQL,SQL 的學習門檻很低,用 SQL 作為跨團隊的開發語言可以很大地提高效率。

穩定。SQL 是一個擁有幾十年曆史的語言,是一個非常穩定的語言,很少有變動。是以當我們更新引擎的版本時,甚至替換成另一個引擎,都可以做到相容地、平滑地更新。

流與批的統一。Blink 底層 runtime 本身就是一個流與批統一的引擎。而 SQL 可以做到 API 層的流與批統一。

我們認為這 5 點對于使用者的易用性是非常重要的,而以上 5 點卻是 DataStream API 所不具備的。是以 Blink 将 SQL 定位為最核心的 API,而不是 DataStream API。

關于流與批的統一是現在業界非常火熱的一個話題,Flink SQL 的流與批統一總結起來就一句話:One Query, One Result。在很多場景,我們既需要批處理,又需要流處理。比如,使用批處理一天跑一個全量,同時使用流處理來做實時的增量更新。在以前經常需要維護兩套引擎,寫兩個 Job,兩個 Job 之間還要維護邏輯的一緻性,這增加了很多的工作量。如果使用 SQL 的話,我們可以讓一份 SQL 代碼既跑在批模式下,又跑在流模式下,這樣使用者隻需要維護一份 SQL 代碼,這是 One Query。而 One Result 是說,同一份 SQL 代碼,在流模式下和批模式下跑出來的結果是一樣的,也就是保證了流式 SQL 的語義正确性。

我們注意到 SQL 是為傳統批處理設計的,不是為流處理設計的。比如說傳統 SQL處理的資料是有限的,而且SQL查詢隻傳回一個結果并結束。但是流上的查詢,處理的資料是無限的,不斷産生結果且不會結束。是以說傳統 SQL 标準中很多定義無法直接映射到流計算中。那麼如何在流上定義 SQL 呢?這裡需要引出 Flink SQL 的核心概念:流與表的二象性。

傳統的 SQL 是定義在表上的,為了能在流上定義 SQL,我們也需要有一個表的概念。這裡就需要引入一個非常重要的概念:動态表(Dynamic Table)。所謂動态表,就是資料會随着時間變化的表,可以想象成就是資料庫中一張被不斷更新的表。我們發現流與表有非常緊密的關系,流可以看做動态表,動态表可以看做流。我們稱之為流表二象性(duality)。

實時計算 Flink SQL 核心功能解密實時計算 Flink SQL 核心功能解密

如上圖所示,一個流可以看做對表的一系列更新操作(changelog),将流從頭開始重放就可以構造成一個動态表。而動态表的每次更新操作都會記錄下 changelog,通過抽取出動态表的 changelog 可以很輕松地得到原始的資料流(類似的思想也被應用于資料庫同步中,如集團的DRC産品)。是以流可以轉換成動态表,動态表又能轉成流,他們之間的轉換不會丢失任何資訊,且保留了一緻的 schema。流是動态表的另一種表現形式,動态表也是流的另一種表現形式,是以說流與表是一種二象性的關系。

上文說到動态表是流的另一種表現形式,有了動态表後,我們就可以在流上定義 SQL 了。流式 SQL 可以想象成連續查詢(Continuous Query)。傳統的查詢是隻運作一次 SQL,産生一個結果就結束了。連續查詢會一直運作在那裡,當每個資料到來,都會持續增量地更新計算結果,進而産生另一個動态表。而這個結果動态表(也就是流)會作為另一個 SQL(連續查詢)的輸入接着計算,進而串起整個資料流圖。

實時計算 Flink SQL 核心功能解密實時計算 Flink SQL 核心功能解密

從 2016 年到 2017 年,Flink SQL 從無到有,迅速發展,解決多個 Stream SQL 領域的難點痛點,快速支援業務的需求。終于在今年的雙11,Flink SQL 支撐了大量的雙11業務,這與其豐富的上下遊系統、完善的功能是離不開的,包括雙流 JOIN,維表 JOIN,TopN,Window,多路輸出等等。

實時計算 Flink SQL 核心功能解密實時計算 Flink SQL 核心功能解密
實時計算 Flink SQL 核心功能解密實時計算 Flink SQL 核心功能解密

雙流 JOIN

雙流 JOIN 功能是将兩條流進行關聯,用來補齊流上的字段。雙流 JOIN 又分為無限流的雙流 JOIN 和帶視窗的雙流 JOIN。

維表 JOIN

TopN

Window

多路輸入、多路輸出

Flink SQL 利用分段優化支援了多路輸出,并且多路輸出的共享節點做到了資源的複用,使得不會計算多次。基于多路輸入、多路輸出的功能,可以将 Flink SQL 作為一個非常簡單易用的畫資料流的工具,可以很容易地構造出一個有流合并、流拆分的複雜 DAG 作業。

MiniBatch 優化

Retraction 撤回機制

借助于阿裡雲一站式開發平台,使用者可以高效地開發 Flink SQL 作業,是業務上線與業務遷移的加速器。目前 Flink SQL 在集團内部已經服務于 雙11回血紅包、聚劃算、飛豬、菜鳥、盒馬、雲零售、反作弊等數十個業務場景,二十多個 BU,并成功經曆雙11大促的考驗。在雙11當天,Flink SQL 的作業更是創下了每秒2.9億條的處理高峰。為各個業務取得了非常好的效果提供了非常堅實的保障。

實時計算 Flink SQL 核心功能解密實時計算 Flink SQL 核心功能解密