本文整理自京東高級技術專家付海濤在 Flink Forward Asia 2020 分享的議題《Apache Flink 在京東的實踐與優化》,內容包括:
1.業務演進和規模
2.容器化實踐
3.Flink 優化改進
4.未來規劃
一、業務演進和規模
1. 業務演進
京東在 2014 年基于 storm 打造了第一代流式處理平臺,可以較好的滿足業務對于數據處理實時性的要求。不過它有一些局限性,對于那些數據量特別大,但是對延遲卻不那么敏感的業務場景,顯得有些力不從心。于是我們在 2017 年引入了 Spark streaming,利用它的微批處理來應對這種業務場景。
隨著業務的發展和業務規模的擴大,我們迫切需要一種兼具低延遲和高吞吐能力,同時支持窗口計算、狀態和恰好一次語義的計算引擎。
2. 業務場景
京東 Flink 服務于京東內部非常多的業務線,主要應用場景包括實時數倉、實時大屏、實時推薦、實時報表、實時風控和實時監控,當然還有其他一些應用場景。總之,實時計算的業務需求,一般都會用 Flink 進行開發。
3. 業務規模
目前我們的 K8s 集群由 5000 多臺機器組成,服務了京東內部 20 多個一級部門。目前在線的流計算任務數有 3000 多,流計算的處理峰值達到 5億條每秒。
二、容器化實踐
下面分享一下容器化的實踐。
在 2017 年,京東內部的大多數任務還是 storm 任務,它們都是跑在物理機上的,同時還有一小部分的 Spark streaming 跑在 Yarn 上。不同的運行環境導致部署和運維的成本特別高,并且在資源利用上有一定的浪費,所以我們迫切需要一個統一集群資源管理和調度系統,來解決這個問題。
經過一系列的嘗試、對比和優化,我們選擇了 K8s。它不僅可以解決部署運維、資源利用的一些問題,還具有云原生彈性自愈、天然容器完整隔離、更易擴展遷移等優點。于是在 2018 年初,我們開始進行容器化的升級改造。
在 2018 年的 6.18,我們只有 20% 的任務跑在 K8s 上;到了 2019 年 2 月份,已經實現了實時計算的所有任務都跑在 K8s 上。容器化后的實時計算平臺經歷了 6.18,雙 11 多次大促,扛住了洪峰壓力,運行的非常穩定。
但是,我們過去的 Flink 容器化方案是基于資源預先分配的靜態方式,不能滿足很多業務場景,于是我們在 2020 年也進行了一個容器化方案的升級,后面會詳細介紹。
容器化帶來非常多的收益,這里主要強調三點:
我們過去的容器化方案是基于 K8s deployment 部署的 Standalone Session 集群。它需要用戶在平臺創建集群時,事先預估出集群所需資源,比如需要的 jobmanager 和 taskmanager 的資源規格和個數,然后平臺通過 K8s 客戶端向 K8s master 發出請求,來創建 jobmanager 的 deployment 和 taskmanager 的 deployment。
其中,整個集群的高可用是基于 ZK 實現;狀態存儲主要是存在 HDFS,有小部分存在 OSS;監控指標 (容器指標、JVM 指標、任務指標) 上報到 Prometheus,結合 Grafana 實現指標的直觀展示;日志是基于我們京東內部的 Logbook 系統進行采集、存儲和查詢。
在實踐中發現,這個方案有兩點不足:
于是我們進行了一個容器化方案的升級,實現了基于 K8s 的動態的資源分配方式。在集群創建的時候,首先我們會根據用戶指定的 job manager 的數量創建 jobmanager 的 deployment;用戶在提交任務的時候,我們會根據任務所需要的資源數,動態的向平臺申請資源,創建 taskmanager。
在運行過程中,如果發現這個任務需要擴容,job manager 會和平臺交互,進行動態擴容;而在發現資源浪費時,會進行縮容。通過這樣一個方式可以很好的解決靜態預分配帶來的問題,并提高了資源利用率。
此處,通過平臺與 K8s 交互進行資源的創建&銷毀,主要基于 4 點考慮:
另外,為了兼容原有 Slot 分配策略 (按 slot 分散),在提交任務時會預估出任務所需資源并一次性申請,同時按照一定的策略進行等待。等到有足夠的資源,能滿足任務運行的需求時,再進行 slot 的分配。這樣很大程度上可以兼容原有的 slot 分散分配策略。
三、Flink 優化改進
下面介紹一下 Flink 的優化改進。
1、預覽拓撲
在業務使用平臺的過程中,我們發現有幾個業務痛點:
為了解決這些問題,我們開發了預覽拓撲的功能:
下面簡單介紹預覽拓撲的工作流程。用戶在平臺提交 SQL 作業或 Jar 作業,這個作業提交之后,會生成一個算子的配置信息,再反饋到我們平臺。我們平臺會把整個拓撲圖預覽出來,然后用戶就可以在線進行算子配置信息的調整。調整完之后,把調整完的配置信息重新提交到我們平臺。并且,這個過程可以是連續調整的,用戶調整完覺得 ok 了就可以提交任務。提交任務之后,整個在線調整的參數就生效了。
這里任務可以多次提交,如何保證前后兩次提交生成算子穩定的對應關系呢?我們采用這樣一個策略:如果你指定了 uidHash 或者 uid,我們就可以拿 uidHash 和 uid 作為這樣一個對應關系的 Key。如果沒有,我們會遍歷整個拓撲圖,按照廣度優先的順序,根據算子在拓撲圖中的位置生成確定的唯一的 ID。拿到唯一的 ID 之后,就可以得到一個確定的關系了。
2、背壓量化
下面介紹一下我們的第二個改進,背壓量化。目前觀測背壓有兩種方式:
針對這個問題,我們的解決方案是采集背壓發生的位置、時間和次數指標,然后上報上去。將量化的背壓監控指標與運行時拓撲結合起來,就可以很直觀的看到背壓產生的影響 (影響任務的位置、時長和次數)。
3、文件系統支持多配置
下面介紹下文件系統支持多配置的功能。
目前在 Flink 中使用文件系統時,會使用 FileSystem.get 傳入 URI,FileSystem 會將 shceme+authority 作為 key 去查找緩存的文件系統,如果不存在,根據 scheme 查找到 FileSystemFactory 調用 create 創建文件系統,返回之后就可以對文件進行操作了。不過,在平臺實踐過程中,經常會遇到這樣的問題:
這兩個問題都涉及到如何讓 Flink 的同一個文件系統支持多套配置。我們的解決方案是通過使用不同的scheme指定和隔離不同的配置。以 HDFS 支持多配置為例,如下圖所示:
我們也做了許多其它的優化和擴展,主要分為三大塊。
四、未來規劃
最后是未來規劃。歸納為 4 點:
原文鏈接:http://click.aliyun.com/m/1000293113/
本文為阿里云原創內容,未經允許不得轉載。