Flink SQL 系列 | 5 個 TableEnvironment 我該用哪個?
本文為 Flink SQL 系列文章的第二篇,前面對 Flink 1.9 Table 新架構及 Planner 的使用進行了詳細說明,本文詳細講解 5 個 TableEnvironment 及其適用場景,並介紹 Flink 社群對 TableEnvironment 的未來規劃。主要內容如下:
- TableEnvironment 簡介
- 5 個 TableEnvironment 梳理
- 如何使用 TableEnvironment
- 社群未來規劃
1. TableEnvironment 簡介
TableEnvironment 是用來建立 Table & SQL 程式的上下文執行環境 ,也是 Table & SQL 程式的入口,Table & SQL 程式的所有功能都是圍繞 TableEnvironment 這個核心類展開的。TableEnvironment 的主要職能包括:對接外部系統,表及後設資料的註冊和檢索,執行SQL語句,提供更詳細的配置選項。
在 Flink 1.8 中,一共有 7 個 TableEnvironment ,在最新的 Flink 1.9 中,社群進行了重構和最佳化,只保留了 5 個TableEnvironment 。本文詳細講解 5 個 TableEnvironment 及其適用場景,並介紹 Flink 社群對 TableEnvironment 的未來規劃。
2. 5 個 TableEnvironment 梳理
Flink 1.9 中保留了 5 個 TableEnvironment,在實現上是 5 個面向使用者的介面,在介面底層進行了不同的實現。5 個介面包括一個 TableEnvironment 介面,兩個 BatchTableEnvironment 介面,兩個 StreamTableEnvironment 介面,5 個介面檔案完整路徑如下:
- org/apache/flink/table/api/TableEnvironment.java
- org/apache/flink/table/api/java/BatchTableEnvironment.java
- org/apache/flink/table/api/scala/BatchTableEnvironment.scala
- org/apache/flink/table/api/java/StreamTableEnvironment.java
- org/apache/flink/table/api/scala/StreamTableEnvironment.scala
結合檔案的路徑,梳理這 5 個介面,我們會發現 TableEnvironment 是頂級介面,是所有 TableEnvironment 的基類 ,BatchTableEnvironment 和 StreamTableEnvironment 都提供了 Java 實現和 Scala 實現 ,分別有兩個介面。
5 個 TableEnvironment
其中,TableEnvironment 作為統一的介面,其統一性體現在兩個方面,一是對於所有基於JVM的語言(即 Scala API 和 Java API 之間沒有區別)是統一的;二是對於 unbounded data (無界資料,即流資料) 和 bounded data (有界資料,即批資料)的處理是統一的。TableEnvironment 提供的是一個純 Table 生態的上下文環境,適用於整個作業都使用 Table API & SQL 編寫程式的場景。TableEnvironment 目前還不支援註冊 UDTF 和 UDAF,使用者有註冊 UDTF 和 UDAF 的需求時,可以選擇使用其他 TableEnvironment。
兩個 StreamTableEnvironment 分別用於 Java 的流計算和 Scala 的流計算場景,流計算的物件分別是 Java 的 DataStream 和 Scala 的 DataStream。相比 TableEnvironment,StreamTableEnvironment 提供了 DataStream 和 Table 之間相互轉換的介面,如果使用者的程式除了使用 Table API & SQL 編寫外,還需要使用到 DataStream API,則需要使用 StreamTableEnvironment。
兩個 BatchTableEnvironment 分別用於 Java 的批處理場景和 Scala 的批處理場景,批處理的物件分別是 Java 的 DataSet 和 Scala 的 DataSet。相比 TableEnvironment,BatchTableEnvironment 提供了 DataSet 和 Table 之間相互轉換的介面,如果使用者的程式除了使用 Table API & SQL 編寫外,還需要使用到 DataSet API,則需要使用 BatchTableEnvironment。
從這五個 TableEnvironment 支援的作業型別 ( Stream 作業和 Batch 作業),支援的 API 型別(DataStream API 和 DataSet API),以及對 UDTF/UDAF 的支援這 5 個方面進行對比,各個TableEnvironment 支援的功能可以歸納如下:
TableEnvironment 支援功能對比
可能大家會疑惑為什麼在 API 需要區分 Java 和 Scala 的兩個 StreamTableEnvironment(或BatchTableEnvironment ),使用的 DataStream也分為 Java DataStream 和 Scala DataStream。
原因主要是 TableEnvironment 的 registerTableFunction方法(用於註冊UDTF) 和 registerAggregateFunction 方法(使用者註冊UDAF) 需要抽取泛型,而現有的 Java 泛型抽取和 Scala 的泛型抽取機制是不一樣的,Java 的抽取是透過反射機制 實現,而 Scala 是透過 Scala macro 實現。此外,由於抽取泛型機制的不一致,作為統一入口的 TableEnvironment 現階段也不支援註冊 UDTF 和 UDAF。針對這個問題,社群已經在計劃引入一套新的型別抽取機制來統一 Java 和 Scala 的型別抽取,實現 Java API 和 Scala API 的統一。
5 個 TableEnvironment 具體實現
結合 Flink planner 和 Blink planner, 進一步梳理 TableEnvironment 的組織關係,我們可以注意到一些有趣的細節:
- 實現流批統一的 Blink planner 中由於沒有了 DataSet 的概念,已經不再使用 BatchTableEnvironment,只會使用 TableEnvironment 和 StreamTableEnvironment,而 Flink planner(即 Old planner) 則支援 5 個 TableEnvironment。
- BatchTableEnvironment 的實現都放到了 Old planner (flink-table-palnner模組) 中,這個模組在社群的未來規劃中是會被逐步刪除的。
3. 如何使用 TableEnvironment
根據使用者使用的 planner 和作業的型別,可以把各個 TableEnvironment 的應用場景分為 4 類,下面結合程式碼來說明在不同的場景下如何使用 TableEnvironment 。
場景一:
使用者使用 Old planner,進行流計算的 Table 程式(使用 Table API 或 SQL 進行開發的程式 )的開發。這種場景下,使用者可以使用 StreamTableEnvironment 或 TableEnvironment ,兩者的區別是 StreamTableEnvironment 額外提供了與 DataStream API 互動的介面。示例程式碼如下:
// **********************
// FLINK STREAMING QUERY USING JAVA
// **********************
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.java.StreamTableEnvironment;
EnvironmentSettings fsSettings = EnvironmentSettings.newInstance().useOldPlanner().inStreamingMode().build();
StreamExecutionEnvironment fsEnv = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment fsTableEnv = StreamTableEnvironment.create(fsEnv, fsSettings);
// or TableEnvironment fsTableEnv = TableEnvironment.create(fsSettings);
// **********************
// FLINK STREAMING QUERY USING SCALA
// **********************
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.table.api.EnvironmentSettings
import org.apache.flink.table.api.scala.StreamTableEnvironment
val fsSettings = EnvironmentSettings.newInstance().useOldPlanner().inStreamingMode().build()
val fsEnv = StreamExecutionEnvironment.getExecutionEnvironment
val fsTableEnv = StreamTableEnvironment.create(fsEnv, fsSettings)
// or val fsTableEnv = TableEnvironment.create(fsSettings)
場景二:
使用者使用 Old planner,進行批處理的 Table 程式的開發。這種場景下,使用者只能使用 BatchTableEnvironment ,因為在使用 Old planner 時,批處理程式操作的資料是 DataSet,只有 BatchTableEnvironment 提供了面向DataSet 的介面實現。示例程式碼如下:
// ******************
// FLINK BATCH QUERY USING JAVA
// ******************
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.table.api.java.BatchTableEnvironment;
ExecutionEnvironment fbEnv = ExecutionEnvironment.getExecutionEnvironment();
BatchTableEnvironment fbTableEnv = BatchTableEnvironment.create(fbEnv);
// ******************
// FLINK BATCH QUERY USING SCALA
// ******************
import org.apache.flink.api.scala.ExecutionEnvironment
import org.apache.flink.table.api.scala.BatchTableEnvironment
val fbEnv = ExecutionEnvironment.getExecutionEnvironment
val fbTableEnv = BatchTableEnvironment.create(fbEnv)
場景三:
使用者使用 Blink planner,進行流計算的 Table 程式的開發。這種場景下,使用者可以使用 StreamTableEnvironment 或 TableEnvironment ,兩者的區別是 StreamTableEnvironment 額外提供與 DataStream API 互動的介面。使用者在 EnvironmentSettings 中宣告使用 Blink planner ,將執行模式設定為 StreamingMode 即可。示例程式碼如下:
// **********************
// BLINK STREAMING QUERY USING JAVA
// **********************
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.java.StreamTableEnvironment;
StreamExecutionEnvironment bsEnv = StreamExecutionEnvironment.getExecutionEnvironment();
EnvironmentSettings bsSettings = EnvironmentSettings.newInstance().useBlinkPlanner().inStreamingMode().build();
StreamTableEnvironment bsTableEnv = StreamTableEnvironment.create(bsEnv, bsSettings);
// or TableEnvironment bsTableEnv = TableEnvironment.create(bsSettings);
// **********************
// BLINK STREAMING QUERY USING SCALA
// **********************
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.table.api.EnvironmentSettings
import org.apache.flink.table.api.scala.StreamTableEnvironment
val bsEnv = StreamExecutionEnvironment.getExecutionEnvironment
val bsSettings = EnvironmentSettings.newInstance().useBlinkPlanner().inStreamingMode().build()
val bsTableEnv = StreamTableEnvironment.create(bsEnv, bsSettings)
// or val bsTableEnv = TableEnvironment.create(bsSettings)
場景四:
使用者使用 Blink planner,進行批處理的 Table 程式的開發。這種場景下,使用者只能使用 TableEnvironment ,因為在使用 Blink planner 時,批處理程式操作的資料已經是 bounded DataStream,所以不能使用 BatchTableEnvironment 。使用者在 EnvironmentSettings 中宣告使用 Blink planner ,將執行模式設定為 BatchMode 即可。值得注意的是,TableEnvironment 介面的具體實現中已經支援了 StreamingMode 和 BatchMode 兩種模式,而 StreamTableEnvironment 介面的具體實現中目前暫不支援 BatchMode 的配置,所以這種場景不能使用 StreamTableEnvironment。示例程式碼如下:
// ******************
// BLINK BATCH QUERY USING JAVA
// ******************
import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.TableEnvironment;
EnvironmentSettings bbSettings = EnvironmentSettings.newInstance().useBlinkPlanner().inBatchMode().build();
TableEnvironment bbTableEnv = TableEnvironment.create(bbSettings);
// ******************
// BLINK BATCH QUERY USING SCALA
// ******************
import org.apache.flink.table.api.{EnvironmentSettings, TableEnvironment}
val bbSettings = EnvironmentSettings.newInstance().useBlinkPlanner().inBatchMode().build()
val bbTableEnv = TableEnvironment.create(bbSettings)
4. 社群未來規劃
目前,社群正在推進 DataStream 的批處理能力,以實現流批技術棧的統一,屆時 DataSet API 會退出歷史的舞臺,兩個 BatchTableEnvironment 也將退出歷史的舞臺。同時社群也在努力推動 Java 和 Scala TableEnvironment 的統一。可以預見的是,Flink TableEnvironment 的未來架構會更加簡潔。TableEnvironment 會是 Flink 推薦使用的入口類,同時能支援 Java API 和 Scala API,還能同時支援流計算作業和批處理作業。只有當需要與 DataStream 做轉換時,才需要用到 StreamTableEnvironment。
本文為雲棲社群原創內容,未經允許不得轉載。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69949601/viewspace-2659557/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 到底該用laravel哪個版本啊Laravel
- 「譯」Java Thread vs AsyncTask:該用哪個?Javathread
- 前端面試一個月,收到了5個offer,該去哪前端面試
- 5 種微服務閘道器,該選哪個?微服務
- concurrent-map 和 sync.Map,我該選擇哪個?
- 5S與VSM,企業應該先做哪個?
- r5和i5處理器哪個好 amd銳龍r5和英特爾i5應該選哪個
- 當下應該學習Python哪個版本?哪個方向好?Python
- 5分鐘從零構建第一個 Apache Flink 應用Apache
- 14個Flink SQL效能最佳化實踐分享SQL
- Bash vs Python:你該使用哪個?Python
- 開發第一個Flink應用
- Apache Flink on K8s:四種執行模式,我該選擇哪種?ApacheK8S模式
- Flink的Job manager中包含了哪三個元件元件
- Java 與 Python:你應該選擇哪個?JavaPython
- 你應該使用哪個雲資料庫?資料庫
- SUSE和Ubuntu,Linux版本該選擇哪個?UbuntuLinux
- 我是一個請求,我該何去何從
- git 中 rebase 是什麼樣的操作,應該從哪個分支rebase到哪個分支Git
- Python和Java該如何選擇?選哪個好?PythonJava
- Flink 1.16:Hive SQL 如何平遷到 Flink SQLHiveSQL
- 系列好文 | Kubernetes 棄用 Docker,我們該何去何從?Docker
- 年末福利分享,雅閣和K5哪個好?我來公佈答案
- 作為一個程式設計新手,我再也不怕Flink迷了我的眼!程式設計
- 安全等保二級和三級哪個高?哪個費用更高?
- openSUSE Leap 與 Tumbleweed,我該選擇哪一個
- 每個 Kubernetes 應聘者應該知道的 5 個面試題面試題
- 每個 Java 開發者都應該知道的 5 個註解Java
- 5個Python整合開發環境,哪個你更喜歡?Python開發環境
- Python UI 開發用哪個好?PythonUI
- 資料分析用哪個系統
- 公司管理用哪個軟體好?
- 幾個場景下用flink如何解決的思考
- 哪個報表工具能抵擋 SQL 注入攻擊SQL
- 應該考慮實施 DataOps 的 5 個理由
- Flink SQL Client初探SQLclient
- 【自動化測試框架】pytest和unitttest你知道多少?區別在哪?該用哪個?框架
- flink快速入門(部署+flink-sql)SQL