实时计算 Flink SQL 核心功能解密
2019獨角獸企業重金招聘Python工程師標準>>>
實時計算 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,近十萬行的代碼)。
為什么是 SQL?
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 的核心概念:流與表的二象性。
Flink SQL 核心概念
動態表 & 流表二象性
傳統的 SQL 是定義在表上的,為了能在流上定義 SQL,我們也需要有一個表的概念。這里就需要引入一個非常重要的概念:動態表(Dynamic Table)。所謂動態表,就是數據會隨著時間變化的表,可以想象成就是數據庫中一張被不斷更新的表。我們發現流與表有非常緊密的關系,流可以看做動態表,動態表可以看做流。我們稱之為流表二象性(duality)。
如上圖所示,一個流可以看做對表的一系列更新操作(changelog),將流從頭開始重放就可以構造成一個動態表。而動態表的每次更新操作都會記錄下 changelog,通過抽取出動態表的 changelog 可以很輕松地得到原始的數據流(類似的思想也被應用于數據庫同步中,如集團的DRC產品)。因此流可以轉換成動態表,動態表又能轉成流,他們之間的轉換不會丟失任何信息,且保留了一致的 schema。流是動態表的另一種表現形式,動態表也是流的另一種表現形式,所以說流與表是一種二象性的關系。
連續查詢
上文說到動態表是流的另一種表現形式,有了動態表后,我們就可以在流上定義 SQL 了。流式 SQL 可以想象成連續查詢(Continuous Query)。傳統的查詢是只運行一次 SQL,產生一個結果就結束了。連續查詢會一直運行在那里,當每個數據到來,都會持續增量地更新計算結果,從而產生另一個動態表。而這個結果動態表(也就是流)會作為另一個 SQL(連續查詢)的輸入接著計算,從而串起整個數據流圖。
Flink SQL 核心功能
從 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)”案例分析》
業務支持情況
借助于阿里云一站式開發平臺,用戶可以高效地開發 Flink SQL 作業,是業務上線與業務遷移的加速器。目前 Flink SQL 在集團內部已經服務于 雙11回血紅包、聚劃算、飛豬、菜鳥、盒馬、云零售、反作弊等數十個業務場景,二十多個 BU,并成功經歷雙11大促的考驗。在雙11當天,Flink SQL 的作業更是創下了每秒2.9億條的處理高峰。為各個業務取得了非常好的效果提供了非常堅實的保障。
轉載于:https://my.oschina.net/u/2935389/blog/3022980
總結
以上是生活随笔為你收集整理的实时计算 Flink SQL 核心功能解密的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: The Sixty-first Of W
- 下一篇: 关于OpenCV中cv2.imwrite