Apache Flink 1.16 正式釋出

danny_2018發表於2022-11-03

Apache Flink 持續保持高速發展,是 Apache 最活躍的社群之一。Flink 1.16 共有 240 多個 Contributor 熱情參與,共完成了 19 個 FLIP [1] 和 1100 多個 issue,給社群帶來非常多振奮人心的功能。

Flink 已經是流計算領域的領跑者,流批一體的概念逐漸得到大家的認可,並在越來越多的公司成功落地。之前的流批一體更強調統一的 API 和統一的計算框架。今年,在此基礎上,Flink 推出了 Streaming Warehouse [2],進一步升級了流批一體的概念:真正完成了流批一體的計算和流批一體的儲存的融合,從而實現流批一體的實時化分析。

在 1.16 版本里,Flink 社群對流、批都完成了眾多改進:

在批處理方面,完成了易用性、穩定性、效能全方位的改進,1.16 是 Fink 批處理的里程碑式的版本,是走向成熟的重要一步。

易用性:引入 SQL Gateway 並完全相容 HiveServer2,使用者可以非常方便的提交 Flink SQL 作業和 Hive SQL 作業,同時也很容易連線到原有的 Hive 生態。

功能:Flink SQL 使用者支援透過 Join Hint 指定 Join 策略,避免不合理的執行計劃;Hive SQL 的相容性已經達到 94%,使用者可以以極低的成本完成 Hive 到 Flink 的遷移。

穩定性:透過預測執行減少作業長尾以提高作業整體執行穩定性;支援自適應 HashJoin,透過失敗回滾機制避免作業失敗。

效能:對多分割槽表進行動態分割槽裁剪以提高處理效率,TPC-DS 在 10TB 規模資料集下效能提升了 30%;支援混合 Shuffle 模式,提高資源使用率和處理效能。

在流處理方面,也完成了很多重大改進:

Changelog State Backend 可以為使用者提供秒級甚至毫秒級 Checkpoint,從而大幅提升容錯體驗,同時為事務性 Sink 作業提供更小的端到端延遲體驗。

維表關聯在流處理中廣泛被使用,引入了通用的快取機制加快維表查詢速度,引入了可配置的非同步模式提升維表查詢吞吐,引入可重試查詢機制解決維表延遲更新問題。這些功能都非常實用,解決了使用者經常抱怨的痛點,支援了更豐富的場景。

從 Flink SQL 誕生第一天就存在一些非確定性操作可能導致使用者作業出現錯誤結果或作業執行異常,這給使用者帶來了極大的困擾。1.16 裡我們花了很多大精力解決了大部分問題,未來還會持續改進。

隨著流批一體的進一步完善和 Flink Table Store 的不斷迭代(0.2版本已釋出 [3]),Flink 社群正一步一步推動 Streaming Warehouse 從概念變為現實並走向成熟。

理解 Streaming Warehouse

流式數倉(Streaming Warehouse)更準確地說,其實是 “make data warehouse streaming”,就是讓整個數倉所有分層的資料全部實時地流動起來,從而實現一個具備端到端實時性的純流服務(Streaming Service),並且用一套統一 API 和計算框架來處理和分析所有流動中的資料。想了解更多內容請參閱文章 [4]。

批處理

得益於我們在流處理的長期投資,流處理已經成為流計算領域的領導者。在批處理上,我們也投入更多的精力,使其成為一個優秀的批處理引擎。流批處理統一的整體體驗也將會更加順暢。

SQL Gateway

從各個渠道反饋中瞭解到,SQL Gateway [5] 一直是使用者非常期待的功能,尤其是對批使用者。1.16 裡,該功能終於完成(設計見FLIP-91 [6])。SQL Gateway 是對 SQL Client 的擴充套件和增強,支援多租戶和外掛式 API 協議(Endpoint),解決了 SQL Client 只能服務單使用者並且不能對接外部服務或元件的問題。當前 SQL Gateway 已支援 REST API 和 HiveServer2 協議,使用者可以透過 cURL,Postman,各種程式語言的 HTTP 客戶端連結到 SQL Gateway 提交流作業、批作業,甚至 OLAP 作業。對於 HiveServer2 協議,請參考“Hive 語法相容”章節。

Hive 語法相容

為了降低從 Hive 到 Flink 的遷移成本,這個版本里我們引入了 HiveServer2 協議並繼續改進 Hive 語法的相容性。

HiveServer2 協議 [7] 允許使用者使用 Hive JDBC/Beeline 和 SQL Gateway 進行互動,Hive 生態(DBeaver, Apache Superset, Apache DolphinScheduler, and Apache Zeppelin)也因此很容易遷移到 Flink。當使用者使用 HiveServer2 協議連線 SQL Gateway,SQL Gateway 會自動註冊 Hive Catalog,自動切換到 Hive 方言,自動使用批處理模式提交作業,使用者可以得到和直接使用 HiveServer2 一樣的體驗。

Hive 語法 [8] 已經是大資料處理的事實標準,Flink 完善了對 Hive 語法的相容,增加了對 Hive 若干生產中常用語法的支援。透過對 Hive 語法的相容,可以幫助使用者將已有的 Hive SQL 任務遷移到 Flink,並且方便熟悉 Hive 語法的使用者使用 Hive 語法編寫 SQL 以查詢註冊進 Flink 中的表。到目前為止,基於 Hive qtest 測試集(包含12K 個 SQL 案例),Hive 2.3 版本的查詢相容性已達到 94.1%,如果排除 ACID 的查詢語句,則已達到 97.3%。

Join Hint

Hint 一直是業界用來干預執行計劃以改善最佳化器缺點的通用解決方案。Join 作為批作業中最廣泛使用的運算元,Flink 支援多種 Join 策略。統計資訊缺失或最佳化器的代價模型不完善都會導致選出錯誤 Join 策略,從而導致作業執行慢甚至有執行失敗的風險。使用者透過指定 Join Hint [9] ,讓最佳化器儘可能選擇使用者指定的 Join 策略,從而避免最佳化器的各種不足,以確保批作業的生產可用性。

自適應 Hash Join

對於批作業而言,資料傾斜是非常常見的,而此時使用 HashJoin 可能執行失敗,這是非常糟糕的體驗。為了解決該問題,我們引入了自適應的 HashJoin:Join 運算元執行時一旦 HashJoin 執行失敗,可以自動回退到 SortMergeJoin,並且是 Task 粒度。透過該機制可確保 HashJoin 運算元始終成功,從而提高了作業的穩定性。

批處理的預測執行

為了解決問題機器導致批作業處理慢的問題,Flink 1.16 引入了預測執行。問題機器是指存在硬體問題、突發 I/O 繁忙或 CPU 負載高等問題的機器,這些問題可能會使得執行在該機器上的任務比其他機器上的任務要慢得多,從而影響批處理作業的整體執行時間。

當啟用預測執行時,Flink 將持續檢測慢任務。一旦檢測到慢任務,該任務所在的機器將被識別為問題機器,並透過黑名單機制(FLIP-224 [10] )被加黑。排程器將為慢任務建立新的執行例項並將它們部署到未被加黑的節點,同時現有執行例項也將繼續執行。新的執行例項和老的執行例項將處理相同的輸入資料併產出相同的結果資料。一旦任何執行例項率先完成,它將被視為該任務的唯一完成執行例項,並且該任務的其餘執行例項都將被取消。

大多數現有 Source 都可以使用預測執行 (FLIP-245 [11] )。只有當一個 Source 使用了 SourceEvent 時,它必須額外實現 SupportsHandleExecutionAttemptSourceEvent 介面以支援預測執行。目前 Sink 尚不支援預測執行,因此預測執行不會在 Sink 上發生。

我們也改進了 Web UI 和 REST API (FLIP-249 [12] ) ,以顯示任務的多個執行例項和被加黑的 TaskManager。

混合 Shuffle 模式

我們為批處理引入了一種新的混合 Shuffle [13] 模式。它結合了 Blocking Shuffle 和 Pipeline Shuffle(主要用於流式處理)的優點:

與 Blocking Shuffle 一樣,它不要求上下游任務同時執行,這允許使用很少的資源執行作業。

與 Pipeline Shuffle 一樣,它不要求上游任務完成後才執行下游任務,這在給定足夠資源情況下減少了作業的整體執行時間。

使用者可以選擇不同的落盤策略,以滿足減少資料落盤或是降低任務重啟代價的不同需求。

注意:該功能為實驗性的,並且預設關閉。

Blocking shuffle 進一步改進

在這個版本中,我們進一步改進了 Blocking Shuffle 的可用性和效能,包括自適應網路緩衝區分配、順序 IO 最佳化和結果分割槽重用,允許多個消費者節點重用同一個物理結果分割槽,以減少磁碟 IO 和儲存空間。在 TPC-DS 10TB規模的測試中,這些最佳化可以實現 7% 的整體效能提升。此外,還引入了兩種壓縮率更高的壓縮演算法(LZO 和 ZSTD)。與預設的 LZ4 壓縮演算法相比,可以進一步減少儲存空間,但要付出一些 CPU 成本。

動態分割槽裁剪

對於批作業,生產環境中分割槽表比非分割槽表使用更為廣泛。當前 Flink 已經支援靜態分割槽裁剪,即在最佳化階段,最佳化器將 Filter 中的 Partition 相關的過濾條件下推到 Source Connector 中從而減少不必要的分割槽讀取。星形模型 [14] 是資料集市模式中最簡單且使用最廣泛的模式,我們發現很多使用者的作業沒法使用靜態分割槽裁剪,因為分割槽裁剪資訊在執行時才能確定,這就需要動態分割槽裁剪技術 [15] ,即執行時根據其他相關表的資料確定分割槽裁剪資訊從而減少對分割槽表中無效分割槽的讀取。透過 TPC-DS 10TB 規模資料集的驗證,該功能可提升 30% 的效能。

流處理

在 1.1 6 中,我們在 Checkpoint、SQL、Connector 和其他領域都進行了改進,從而確保 Flink 在流計算領域繼續領先。

Generalized Incremental Checkpoint

Changelog State Backend 旨在令 Checkpoint 的間隔更短、更加可預測。這個版本在自身易用性上和與其他 State Backend 相容性上做了諸多改進,使其達到生產可用。

支援狀態遷移

支援 Failover 時從本地恢復

引入檔案快取最佳化恢復過程的效能

支援從 Checkpoint 進行切換

最佳化監控體驗:

擴充了 Changelog 的監控指標

在 Flink WebUI 上顯示 Changelog 相關的配置

表 1: Value State 上 Changelog Enabled / Changelog Disabled 對比 (詳細配置請參考文件 [16] )

RocksDB Rescaling 改進及效能測試

對於使用 Flink 構建的雲服務應用來說,Rescaling 是一種非常頻繁的操作。這個版本使用了 RocksDB 的區間刪除 [17] 來最佳化增量 RocksDB State Backend 的 Rescaling 效能。區間刪除被用來避免在 Rescaling 過程中大量的掃描和單點刪除操作,對有大量的狀態需要刪除的擴併發來說,單個併發上的恢復速度可以提高 2~10 倍 [18] 。

改善 State Backend 的監測體驗和可用性

這個版本還改善了狀態後臺的監控體驗和可用性。之前,RocksDB 的日誌位於它自己的 DB 目錄中,這使得除錯 RocksDB 沒那麼容易。這個版本讓 RocksDB 的日誌預設留在 Flink 的日誌目錄中。新增了 RocksDB 相關的統計指標,以幫助除錯 DB 級別的效能,例如,在 DB 內的總塊快取命中/失敗計數。

支援透支緩衝區

透支緩衝區 [19] (Overdraft Buffers)旨在緩解反壓情況下 Subtask 被阻塞的機率,可以透過設定 taskmanager.network.memory.max-overdraft-buffers-per-gate [20] 開啟。

從 1.16 開始,一個 Flink 的 Subtask 可以申請 5 個(預設)額外的透支緩衝區。透支緩衝區會輕微地增加作業的記憶體使用量,但可以極大地減少 Checkpoint 的間隔,特別是在開啟 Unaligned Checkpoint 情況下。只有當前 Subtask 被下游 Subtasks 反壓且當前 Subtask 需要請求超過 1 個網路緩衝區(Network Buffer)才能完成當前的操作時,透支緩衝區才會被使用。更多細節可以參考文件 [21] 。

對齊 Checkpoint 超時

這個版本更新了從 Aligned Checkpoint(AC) 切換到 Unaligned Checkpoint (UC) 的時間點。在開啟 UC 的情況下,如果配置了execution.checkpointing.aligned-checkpoint-timeout [22] , 在啟動時每個 Checkpoint 仍然是 AC,但當全域性 Checkpoint 持續時間超過 aligned-checkpoint-timeout 時, 如果 AC 還沒完成,那麼 Checkpoint 將會轉換為 UC。

以前,對一個 Substask 來說,AC 到 UC 的切換需要等所有上游的 Barriers 到達後才能開始,在反壓嚴重的情況下,在 checkpointing-timeout [23] 過期之前,下游的 Substask 可能無法完全地收到所有 Barriers,從而導致 Checkpoint 失敗。

在這個版本中,如果上游 Subtask 中的 Barrier 無法在 execution.checkpointing.aligned-checkpoint-timeout [24] 內傳送到下游,Flink 會讓上游的 Subtask 先切換成 UC,以把 Barrier 傳送到下游,從而減少反壓情況下 Checkpoint 超時的機率。更多細節可以參考文件 [25] 。

流計算的非確定性

Flink SQL 使用者經常抱怨理解流處理的成本太高,其中一個痛點是流處理中的非確定性(而且通常不直觀),它可能會導致錯誤的結果或異常。而這些痛點在 Flink SQL 的早期就已經存在了。

對於複雜的流作業,現在可以在執行前檢測並解決潛在的正確性問題。如果問題不能完全解決,一個詳細的訊息可以提示使用者如何調整 SQL,以避免引入非確定性問題。更多細節可以參考文件 [26] 。

維表增強

維表關聯在流處理中被廣泛使用,在 1.16 中我們為此加入了多項最佳化和增強:

支援了通用的快取機制和相關指標 [27] ,可以加速維表查詢。

透過作業配置 [28] 或查詢提示 [29] 支援可配置的非同步模式(ALLOW_UNORDERED),在不影響正確性的前提下大大提升查詢吞吐。

可重試的查詢機制 [30] 讓使用者解決維表資料更新延遲問題有了更多的手段。

非同步 I/O 支援重試

為非同步 I/O [31] 引入了內建的重試機制,它對使用者現有程式碼是透明的,可以靈活地滿足使用者的重試和異常處理需求。

PyFlink

在 Flink 1.15 中,我們引入了一種新的執行模式:“執行緒”模式。在該模式下,使用者自定義的 Python 函式將透過 JNI 在 JVM 中執行,而不是在獨立的 Python 程式中執行。但是,在 Flink 1.15 中,僅在 Table API 和 SQL 上的 Python 標量函式的執行上支援了該功能。在該版本中,我們對該功能提供了更全面的支援,在 Python DataStream API 中以及在 Table API 和 SQL 的 Python 表值函式中,也支援了該功能。

除此之外,我們還在持續補全 Python API 所缺失的最後幾處功能。在這個版本中,我們對 Python DataStream API 提供了更全面的支援:支援了旁路輸出、Broadcast State 等功能,並完善了對於視窗功能的支援。我們還在 Python DataStream API 中,新增了對於更多的 Connector 以及 Format 的支援,例如新增了對於 Elasticsearch、Kinesis、Pulsar、Hybrid Source 等 Connector 的支援以及對於 Orc、Parquet 等 Format 的支援。有了這些功能之後,Python API 已經基本對齊了 Java 和 Scala API 中絕大部分的重要功能,使用者已經可以使用 Python 語言完成大多數型別 Flink 作業的開發。

其他

新語法

1.16 擴充套件了多個 DDL 語法以幫助使用者更好的使用 SQL:

USING JAR [32] 支援動態載入 UDF jar包,方便平臺開發者輕鬆實現 UDF 的管理和相關作業的提交。

CREATE TABLE AS SELECT [33] (CTAS) 方便使用者基於已有的表和查詢建立新的表。

ANALYZE TABLE [34] 支援使用者手工為原表生成統計資訊,以便最佳化器可以生成更優的執行計劃。

DataStream 中的快取

支援透過 DataStream#cache 快取 Transformation 的執行結果。快取的中間結果在首次計算中間結果時才生成,以便以後的作業可以重用該結果。如果快取丟失,原始的 Transformation 將會被重新計算以得到結果。目前該功能只在批處理模式下支援。這個功能對於 Python 中的 ML 和互動式程式設計非常有用。

History Server 及已完成作業的資訊增強

在這個版本中,我們加強了檢視已完成作業的資訊的體驗。

JobManager / HistoryServer WebUI 提供了詳細的執行時間指標,包括任務在每個執行狀態下的耗時,以及在執行過程中繁忙/空閒/反壓總時間。

JobManager / HistoryServer WebUI 提供了按 Task 或者 TaskManager 維度分組的主要子任務指標的聚合。

JobManager / HistoryServer WebUI 提供了更多的環境資訊,包括環境變數,JVM 選項和 Classpath。

HistoryServer 現在支援從外部日誌歸檔服務中瀏覽日誌,更多細節可以參考文件 [35] 。

Protobuf 格式

Flink 現在支援 Protocol Buffers [36] (Protobuf) 格式,這允許您直接在 Table API 或 SQL 應用程式中使用這種格式。

為非同步 Sink 引入可配置的 RateLimitingStrategy

1.15 中實現了非同步 Sink,允許使用者輕鬆實現自定義非同步 Sink。這個版本里,我們對此進行擴充套件以支援可配置的 RateLimitingStrategy。這意味著 Sink 的實現者現在可以自定義其非同步 Sink 在請求失敗時的行為方式,具體行為取決於特定的 Sink。如果沒有指定 RateLimitingStrategy,它將預設使用 AIMDScalingStrategy。

來自 “ Apache Flink ”, 原文作者:Apache Flink;原文連結:https://mp.weixin.qq.com/s/feWJXr6rd6CRqHTvzKFkRg,如有侵權,請聯絡管理員刪除。

相關文章