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