摘要:本文整理自 Apache Flink PMC&Committer 伍翀(雲邪)在 9 月 24 日 Apache Flink Meetup 的演講。主要內容包括:
- Hive SQL 遷移的動機
- Hive SQL 遷移的挑戰
- Hive SQL 遷移的實踐
- Hive SQL 遷移的演示
- 未來規劃
一、Hive SQL 遷移的動機
Flink 已經是流計算的事實標準,當前國內外做實時計算或流計算一般都會選擇 Flink 和 Flink SQL。另外,Flink 也是是家喻戶曉的流批一體大資料計算引擎。
然而,目前 Flink 也面臨著挑戰。比如雖然現在大規模應用都以流計算為主,但 Flink 批計算的應用並不廣泛,想要進一步推動真正意義上的流批一體落地,需要推動業界更多地落地 Flink 批計算,需要更積極地擁抱現有的離線生態。當前業界離線生態主要以 Hive 為主,因此我們在過去版本中做了很多與 Hive 相關的整合,包括 Hive Catalog、Hive 語法相容、Hive UDF 相容、流式寫入 Hive 等。在 Flink 1.16 版本中,我們進一步提升了 HiveSQL 的相容度,還支援了 HiveServer2 的協議相容。
所以,為什麼 Flink 要去支援 Hive SQL 的遷移?一方面,我們希望吸引更多的 Hive 離線數倉使用者,透過使用者來不斷打磨批計算引擎,對齊主流批計算引擎。另一方面,透過相容 Hive SQL,來降低現有離線使用者使用 Flink 開發離線業務的門檻。除此之外,另外,生態是開源產品的最大門檻。Flink 已經擁有非常豐富的實時生態工具,但離線生態依然較為欠缺。透過相容 Hive 生態可以快速融入 Hive 離線生態工具和平臺,降低使用者接入的成本。最後,這也是實現流批一體的重要一環,我們希望推動業界嘗試統一的流計算和批計算引擎,再統一流計算和批計算 SQL。
從使用者角度來看,Hive SQL 為什麼要遷移到 Flink SQL 上?
對於平臺方而言,統一流批計算引擎,只需維護一套 Flink 引擎,可以降低維護成本,提升團隊研發效率。另外,可以利用 Flink + Gateway+ HiveSQL 相容,快速建設一套 OLAP 系統。Flink 的另一優勢是擁有豐富的 connector 生態,可以藉助 Flink 豐富的資料來源實現強大的聯邦查詢。比如不僅可以在 Hive 數倉裡做 ad-hoc 查詢,也可以將 Hive 表資料與 MySQL、HBase、Iceberg、Hudi 等資料來源做聯邦查詢等。
對於離線數倉使用者而言,可以用 Hive SQL 寫流計算作業,極大降低實時化改造成本。使用的依然是以前的 HiveSQL 語法,但是可以執行在 streaming 模式下。在此基礎之上也可以進一步探索流批一體 SQL 層以及流批一體數倉層的建設。
二、Hive SQL 遷移的挑戰
但是 Flink 支援 HiveSQL 的遷移面臨著很多挑戰,主要有以下三個方面:
- 相容:包括離線數倉作業和Hive平臺工具的相容。主要對應使用者層的相容和平臺方的相容。
- 穩定性:遷移後的作業首先要保證生產的穩定性。我們在1.16中也做了很多這方面的工作,包括FLIP-168 預測執行和Adaptive Hash Join。後續我們會發表更多的文章來介紹這方面的工作。
- 效能:最後效能也是很重要的,在1.16中我們也做了很多這方面的工作,包括Dynamic Partition Pruning(DPP)、後設資料訪問加速等,後續也會發表更多文章來介紹這方面的工作。
接下來我們重點講解下 Hive 相容相關的工作。
Hive 語法的相容並沒有完全造出一套新的 SQL 引擎,而是複用了 Flink SQL 的很多核心流程和程式碼。我們抽象出了可插拔的 parser 層來支援和擴充套件不同的語法。Flink SQL 會經過 Flink Parser 轉換成 Flink RelNode,再經過 Logical Plan 最佳化為 Physical Plan,最後轉換為 Job Graph 提交執行。為了支援 Hive 語法相容,我們引入了 Hive Parser 元件,來將 Hive SQL 轉化成 Flink RelNode。這個過程中,複用了大部分 Hive 現有的 SQL 解析邏輯,保證語法層的相容(均基於 Calcite)。之後 RelNode 複用同樣的流程和程式碼轉化成 LogicalPlan、Physical Plan、JobGraph,最後提交執行。
從架構上看,Hive 語法相容並不複雜,但這是一個“魔鬼在細節”的工作。上圖為部分 Flink1.16 版本里 Flink Hive 相容相關的 issue,涉及 query 相容、型別系統、語義、行為、DDL、DML、輔助查詢命令等非常多語法功能。累計完成的 issue 數達近百個。
Flink1.16 版本將 Hive 相容度從 85% 提升至 94.1%。相容度測試主要依靠 Hive qtest 測試集,其中包含 12,000 多個測試 case,覆蓋了 Hive 目前所有主流語法功能。沒有相容的一部分包括 ACID 功能(業界使用較少),如果除去 ACID 功能,相容度已達 97%以上。
SQLGateway 是 Flink SQL 的 server 層元件,是單獨的程式,對標 HiveServer2 元件。從 Flink 整體架構上看,SQLGateway 處於中間位置。
向下,封裝了使用者 API 的 Flink SQL 和 Hive SQL。不管是 Flink SQL 還是 Hive SQL,都使用 Flink 流批一體的 Runtime 來執行,可以執行在批模式,也可以執行在流模式。Flink 的資源也可以部署執行在 YARN、K8S、Flink standalone 叢集上。
向上,SQLGateway 提供了可插拔協議層 Endpoint,目前提供了 HiveServer2 和 REST 兩種協議實現。透過 HiveServer2 Endpoint,使用者可以將 Hive 生態的很多工具和元件(Zeppelin、Superset、Beeline、DBeaver 等)連線到 SQL Gateway,提供流批統一的 SQL 服務併相容 Hive SQL。透過 REST 協議可以使用 Postman、curl 命令或自己透過 Python、Java 程式設計來訪問,提供完善和靈活的流計算服務。將來,Endpoint 能力也會繼續擴充套件,比如可以提供更高效能的 gRPC 協議或相容 PG 協議。
三、Hive SQL 遷移的實踐
目前快手正在與 Flink 社群緊密合作,推進流批一體的落地。目前快手遷移 Hive SQL 作業到 Flink SQL 作業已經取得了初步的進展,已有上千個作業完成了遷移。快手的遷移主要策略為雙跑平臺,已有業務繼續執行,雙跑平臺有智慧路由元件,可以透過指定規則或 pattern 識別出作業,投遞到 MapReduce、Spark 或 Flink 上執行。初期的執行較為謹慎,會透過白名單機制指定某些作業先執行在 Flink,觀察其穩定性與效能,對比其結果一致性,後續逐步透過規則來放量。更多的實踐經驗與細節可以關注 Flink Forward Asia 2022 上分享的《Hive SQL 遷移到 Flink SQL 在快手的實踐》。
四、Hive SQL 遷移的演示
Demo1:Hive SQL 如何遷移到 Flink SQL
接下來演示一下 Hive SQL 如何遷移到 Flink SQL。我們已經搭建好一個 YARN 叢集,以及 Hive 相關元件,包括 HiveServer2 的服務。我們使用 Zeppelin 做資料視覺化和 SQL 查詢。我們將演示 Hive SQL 遷移到 Flink SQL 只需改一行地址,Zeppelin 體驗並無二致,SQL 也無需修改。完整的 Demo 影片請觀看完整的演講影片: https://www.bilibili.com/vide...
首先在 Zeppelin 中配置 Hive Interpreter,填入 HiveServer2 的 JDBC 地址和埠、使用者名稱密碼、Driver 等資訊。
使用當前的 Hive Interpreter,我們可以透過 Hive DDL 命令建立一張打寬的 store_sale_detail 表。使用 Hive SQL 語法關聯 store_sales、date_dim、store 三張表,打成一張寬表寫到 store_sale_detail。執行該 INSERT INTO 語句後,便能在 Hadoop 平臺上看到執行起來的 MapReduce 任務。
store_sale_detail 明細寬表生產完後,我們就可以進行查詢分析,比如檢視星期天每個店鋪的銷量。執行完後可透過餅圖等多種形式展示結果。
上面簡單演示了使用 Hive 進行資料生產和資料分析,其中計算引擎使用的是 Hive 原生的 Hadoop MapReduce 作業,作業執行在 YARN 叢集上。接下來我們開始遷移到 Flink SQL,作業仍然執行在 YARN 叢集上。
首先搭建 Flink SQL 叢集以及啟動 SQLGateway。我們已經下載並解壓了 Flink 1.16 版本。其中 lib 資料夾下也已經提前準備 Hive connector、JDBC connector 和 MySQL Driver。另外,還需要將 flink-table-planner-loader 與 opt/ 目錄下的 flink-table-planner JAR 包做個替換,然後啟動 YARN session 叢集。Session 叢集啟動後,可在 yarn 上看到 Flink 的 session application。
在啟動 SQLGateway 之前,需要先修改配置,主要配置 HiveServer2 Endpoint 相關的資訊。
此處 SQLGateway 的 endpoint type 是 HiveServer2,以及需要額外設定三個配置:
HiveServer2 的 hive-conf-dir、thrift.host 以及 thrift.port。這裡注意我們啟動的埠號是 20002。然後透過 sql-gateway.sh start 命令啟動 SQL Gateway 服務。
啟動後便可以進行遷移。因為 HiveServer2 執行在同一臺機器上,因此只需修改埠號即可。將此處 10000 埠號改為剛剛啟動的 20002 埠號,即 Flink SQLGateway 的埠,無需進行任何其他改動。重啟 interpreter,遷移完成!
接著我們可以在 Zeppelin 中重新執行一遍剛剛的 Hive SQL 語句,可以發現結果都是一致的。
如上圖所示,是查詢每個商店在週日的銷售總額的結果,其餅圖結果與使用 Hive 引擎查詢的結果完全一致,不同的是這次的查詢是執行在 Flink 引擎之上。
Hive SQL 遷移到 Flink SQL 後不僅能獲得更好的效能,還能獲得 Flink SQL 提供的額外能力,包括更豐富的聯邦查詢和流批一體能力。
我們可以用 Flink DDL 建立新的 catalog,比如 MySQL 表裡還有新的額外的維度資訊,不在 Hive 中,希望關聯它做新資料的探查。只需使用 Flink 的 CREATE CATALOG 語句建立 MySQL catalog,即可實現聯邦查詢。同時,Flink 會將能下推的 projection、filter 等都下推到 MySQL 進行裁剪。
除此之外,也可以使用 Hive SQL 體驗流計算的能力。使用 Flink 語法建立一張 datagen 表,該表會源源不斷產生隨機資料。再切回 Hive 語法建立一張 Hive 結果表 sink。將執行模式改為 streaming,執行 insert into 語句,便提交了一個流作業,該作業會源源不斷地將 datagen 中生成的資料流式地寫入 Hive。
為了驗證 Hive 結果表一直在被流作業寫入資料,我們也可以用 Hive 語法查詢寫入的表。如上圖所示,透過不斷執行 count(*) 語句,可以看到該表一直在寫入資料,因此查詢結果會不斷變化。
五、未來規劃
未來,Flink 將在以下三個方面持續演進:
- 第一,持續在 batch 上做更多嘗試和投入,提升 batch 的穩定性和效能,目標是短期內能夠追齊主流的批計算引擎。
- 第二,完善資料湖的分析,比如更高效的批式資料湖讀寫、查詢最佳化下推、列存上的讀寫最佳化,Iceberg、Hudi 以及 Flink Table Store 的支援等。另外,也會提供豐富的湖上資料查詢和管理功能,比如查詢快照版本的能力、查詢後設資料、更豐富的 DML 語法(UPDATE、DELETE、MERGE INTO)以及管理湖上資料 CALL 命令等。
- 第三,Flink Batch 生態建設,包括進一步完善 Remote Shuffle Service、血緣管理等。
Q&A
Q:Hive 寫透過 Flink 執行,如果 Hive 資料量特別大,是否會出現記憶體不足、OOM 等報錯?
A:目前 Flink 執行 batch 模式下,基本所有運算元裡都有記憶體管理機制。資料不是以 Java 物件的方式存在 Flink,而是在 Java 記憶體裡面開闢了單獨的記憶體空間供其使用。如果記憶體滿,則會做落盤、spill,速度可能會略微下降,但一般不會發生記憶體 OOM。
Q:Flink 是否支援 Hive 自定義 UDF 函式?遷移成本如何?
A:支援,可直接遷移。
Q:現有的離線數倉從 Hive 遷到 Flink 是否存在風險?平滑遷移的注意點有哪些?
A:平滑遷移目前大多使用雙跑平臺,透過機制挑選出部分作業先進行遷移,遷移的作業在兩個平臺同時執行,因此需要驗證行為、結果是否一致,然後逐漸將老平臺的作業下線,變為單跑。整個過程需要循序漸進,通常需要半年至一年的時間。
Q:Demo 中有一個 SQL 查詢使用了 Hive on MR 引擎,遷移之後是走 Flink SQLGateway 還是 Hive on MR 模式?
A:遷移後,因為配置的埠是 Flink SQL Gateway 的埠,所以 SQL 請求走的是 Flink SQL Gateway,Gateway 會將 Hive SQL 編譯成 Flink 作業提交到 YARN 叢集上執行。
Q:Flink 執行批次任務時,TaskManager 個數是我們指定還是自動生成?
A:對於 standalone 模式,包括執行在 k8s 上的 standalone 模式,TM 數量由使用者指定。其他模式下,TM 數量都由 Flink 自己決定和拉起,包括 yarn/k8s application 模式,yarn session 模式, yarn per-job 模式,native k8s session 模式。拉起的 TM 數量和作業請求的 slot 數相關,taskmanager.numberOfTaskSlots 引數決定了 slot 與 TM 個數的對映關係,slot 數量則和被排程的作業節點的併發度相關。
Q:Flink 執行在 K8S 上時,如果啟用了動態資源分配,shuffle 資料會一直儲存在 POD 磁碟上嗎?
A:可以選擇,可以 on TM 也可以 on RemoteShuffleService。
Q:離線作業遷移後,是否還支援 with as 語法以及 partition by 語法?
A:WITH AS 語法依然支援,CREATE TABLE 中的 PARTITIONED BY 語法也仍然支援。
Flink 1.16.0 已如期釋出,歡迎大家體驗和使用 Hive SQL 遷移的能力,也歡迎加入【Flink Batch 交流群】交流和反饋相關的問題和想法。
活動推薦
阿里雲基於 Apache Flink 構建的企業級產品-實時計算Flink版現開啟活動:
99 元試用 實時計算Flink版(包年包月、10CU)即有機會獲得 Flink 獨家定製衛衣;另包 3 個月及以上還有 85 折優惠!
瞭解活動詳情:https://www.aliyun.com/produc...