Flink SQL 是於2017年7月開始面向集團開放流計算服務的。雖然是一個很是年輕的產品,可是到雙11期間已經支撐了數千個做業,在雙11期間,Blink 做業的處理峯值達到了5+億每秒,而其中僅 Flink SQL 做業的處理總峯值就達到了3億/秒。Flink SQL 在這麼短的時間內支撐了如此多的業務,與其穩定的內核、完善的功能、強大的生態是分不開的。html
本文會帶着你們一塊兒來揭開 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 具備如下幾個優勢:異步
咱們認爲這 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)。優化
如上圖所示,一個流能夠看作對錶的一系列更新操做(changelog),將流從頭開始重放就能夠構形成一個動態表。而動態表的每次更新操做都會記錄下 changelog,經過抽取出動態表的 changelog 能夠很輕鬆地獲得原始的數據流(相似的思想也被應用於數據庫同步中,如集團的DRC產品)。所以流能夠轉換成動態表,動態表又能轉成流,他們之間的轉換不會丟失任何信息,且保留了一致的 schema。流是動態表的另外一種表現形式,動態表也是流的另外一種表現形式,因此說流與表是一種二象性的關係。阿里雲
上文說到動態表是流的另外一種表現形式,有了動態表後,咱們就能夠在流上定義 SQL 了。流式 SQL 能夠想象成連續查詢(Continuous Query)。傳統的查詢是隻運行一次 SQL,產生一個結果就結束了。連續查詢會一直運行在那裏,當每一個數據到來,都會持續增量地更新計算結果,從而產生另外一個動態表。而這個結果動態表(也就是流)會做爲另外一個 SQL(連續查詢)的輸入接着計算,從而串起整個數據流圖。spa
從 2016 年到 2017 年,Flink SQL 從無到有,迅速發展,解決多個 Stream SQL 領域的難點痛點,快速支持業務的需求。終於在今年的雙11,Flink SQL 支撐了大量的雙11業務,這與其豐富的上下游系統、完善的功能是離不開的,包括雙流 JOIN,維表 JOIN,TopN,Window,多路輸出等等。插件
Flink SQL 接入了集團內常見的十多種上下游系統,包括了11種結果表插件、5種源表插件、4種維表插件。只須要聲明對接系統的類型,就能完成上下游系統的鏈接,將你從阿里雲存儲五花八門的 SDK 中解放出來。詳見《Flink SQL 功能解密系列 —— 阿里雲流計算/Blink支持的connectors》
雙流 JOIN
雙流 JOIN 功能是將兩條流進行關聯,用來補齊流上的字段。雙流 JOIN 又分爲無限流的雙流 JOIN 和帶窗口的雙流 JOIN。
維表 JOIN
維表 JOIN 功能是流與表的關聯,也是用來爲數據流補齊字段,只是補齊的維度字段是在外部存儲的維表中的。咱們爲維表 JOIN 作了諸如 Async、cache、multi-join-merge 等優化,使得維表 JOIN 的性能很是優異。具體原理分析和最佳實踐能夠閱讀《Flink SQL 功能解密系列 —— 維表 JOIN 與異步優化》
TopN
TopN 是統計報表和大屏很是常見的功能,主要用來實時計算排行榜。除了全局 TopN 功能外,咱們還提供了分組 TopN 的功能。流上的 TopN 有很是多的挑戰。具體原理分析和實踐推薦閱讀《Flink SQL 功能解密系列 —— 流式 TopN 的挑戰與實現》
Window
Flink SQL 簡單易用的一大特點就是支持開箱即用的 Window 功能。支持滾動窗口(Tumble)、滑動窗口(Hop)、會話窗口(Session)以及傳統數據庫中的OVER窗口。具體使用方式能夠閱讀《Window 文檔》
多路輸入、多路輸出
Flink SQL 利用分段優化支持了多路輸出,而且多路輸出的共享節點作到了資源的複用,使得不會計算屢次。基於多路輸入、多路輸出的功能,能夠將 Flink SQL 做爲一個很是簡單易用的畫數據流的工具,能夠很容易地構造出一個有流合併、流拆分的複雜 DAG 做業。
MiniBatch 優化
除此以外,咱們還在 SQL 上作了不少的優化。其中 MiniBatch 就是核心優化之一。對於有狀態的算子來講,每一個進入算子的元素都須要對狀態作序列化/反序列化的操做,頻繁的狀態序列化/反序列化操做佔了性能開銷的大半。MiniBatch 的核心思想是,對進入算子的元素進行攢批,一批數據只須要對狀態序列化/反序列化一次便可,極大地提高了性能。詳細的原理實現推薦閱讀《Flink SQL 功能解密系列 —— 解決熱點問題的大殺器 MiniBatch》
Retraction 撤回機制
撤回機制是 Flink SQL 中一個很是重要的基石,它解決了 early-fire 致使的結果正確性問題(全部的 GroupBy 都是 early-fire 的)。而利用好撤回機制有時候可以很巧妙地幫助業務解決一些特殊需求。詳細的業務應用分析推薦閱讀《Flink SQL 功能解密系列 —— 流計算「撤回(Retraction)」案例分析》