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