導讀:Flink是目前流式處理領域的熱門引擎,在實時數倉、實時風控、實時推薦等多個場景有著廣泛的應用。京東於2018年開始基於Flink+k8s深入打造高效能、穩定、可靠、易用的實時計算平臺,支撐了京東內部多條業務線平穩度過618、雙11多次大促。本文將分享京東Flink在應用過程中遇到的問題、挑戰和解決方案,在效能、穩定性、易用性等方面對社群版Flink所做的深入的定製和最佳化,以及未來的展望和規劃。今天的分享主要分為三個部分:
- 演進和應用
- Flink最佳化改進
- 未來規劃
01
演進和應用
首先給大家介紹Flink在京東的發展歷程、平臺架構、應用和業務規模。
1. 發展歷程
京東在2014年基於storm打造了第一代流式處理平臺,它可以較好的滿足資料處理的實時性要求。不過它有一些侷限性,比如對於一些資料量特別大的場景,顯得有些力不從心。於是我們在2017年引入了spark streaming,利用它的微批處理來應對這種業務場景。隨著業務的發展和業務規模的擴大,2018年我們引入了具有低延遲、高吞吐,同時支援狀態計算和恰好一次語義能力的新一代計算引擎Flink,同時開始基於k8s進行實時計算的容器化升級。到2019年,實時計算全部跑在k8s上了,我們基於Flink1.8開始打造全新的SQL平臺。在2020、2021年,我們進行了統一引擎的工作,並初步支援智慧診斷和彈性伸縮,過去流處理是我們關注的重點,我們平臺也開始支援批處理,整個平臺朝著流批一體智慧化的方向演進。
2. 平臺架構
京東實時計算平臺以Flink為核心,部署在K8S叢集上,狀態儲存在HDFS中,用Zoopkeeper來實現高可用。支援京東內部自研訊息佇列JDQ,資料可以寫入Hive、HBase等儲存裡。
3. 應用場景
目前絕大多數實時場景都會透過Flink來計算,同時部分批處理的任務也會用Flink來支援。
4. 業務規模
02
Flink最佳化改進
京東在效能、穩定性、易用性等方面對社群版Flink做了深入的定製和最佳化工作。
1. 預覽拓撲
支援使用者提交作業之後可以預覽拓撲,可以選中每一個運算元進行並行度設定和槽位的分組預覽,同時也可以清楚的看到網路資源的使用情況等等,透過這樣的方式使用者可以非常方便的對任務進行調優。
在修改拓撲配置的時候,我們通常需要知道運算元和配置之間的穩定關係,對於運算元我們會根據透過使用者在運算元中指定的uidHash或者uid,或者運算元在拓撲中的位置如前後關係來生成一個唯一的key與配置構成穩定的對應關係。使用者可以線上調整運算元的配置並進行預覽。
2. 背壓量化
當下遊消費跟不上上游的資料生產時,作業會遇到一些瓶頸,可以透過Flink UI的Monitor看到背壓的高低和位置。這種方式存在一些問題:
- 有的場景下采集不到背壓
- 無法跟蹤歷史背壓情況
- 背壓影響不直觀
- 大並行度時被壓採集壓力大
還可以透過Flink Task Metries來檢視被壓情況,這種方式可以解決追蹤歷史背壓的問題,支援將背壓情況採集到普米修斯或其他服務裡進行歷史的檢視。但仍存在下面一些問題:
- 不同的Flink版本指標差異
- 分析背壓有一定門檻
- 背壓影響不直觀
最佳化方案:
- 採集背壓發生的位置、時間和次數指標作為指標上報
- 背壓監控+執行拓撲,精準反映背壓現場情況
3. 檔案系統支援多配置
改進背景:業務人員希望把狀態放在公共叢集,同時又想讀取業務集市裡業務資料;使用者希望把資料從一個OSS儲存讀出,處理後到另一個OSS儲存。
解決方案:基於Flink檔案系統的基本機制進行改進,使用不同的schema將不同的服務的配置進行隔離。
4. 資料分發最佳化
最佳化背景:在運算元上下游並行度不一樣時,在Flink中預設資料分發機制是rebalance,即將所有資料依次分發給下游所有的並行度,這種分發機制一般情況下都是可以很好的工作的。不過,對於一些特殊場景,可以進一步最佳化提升計算效能。
① 採用基於負載的動態的rebalance
當下遊運算元的各個Task負載不均衡時,處理最慢的Task將會成為計算的瓶頸,為此我們開發了基於下游負載情況進行動態分發的動態rebalance機制:上游運算元Task在分發資料時,優先發送給下游處理最快的Task,而不是採用round-robin的方式均分發送。透過這種最佳化,我們經過大量測試發現,在負載不均衡的場景中計算效能可以提升近一倍。
② 使用rescale代替rebalance
如果上游並行度資料比較均勻且上下游並行度數量成比例,此時就可以採用rescale代替rebalance機制提升效能。實現機制是將上游每個並行度的輸出資料按照下游並行度進行分割槽分發,不是分發到下游所有並行度,比如上游運算元並行度為2,下游運算元並行度為4,就可以將上游的第一個並行度的資料分發到下游前2個並行度,上游第二個並行度的資料分發到下游後2個並行度。
這種分發機制不僅減少了網路buffer,提高了網路效率,還降低了上下游的相關程度,有利於使用Flink的region機制進行故障恢復。
5. 最後一次CP作為SP
最佳化背景:在異常情況下需要進行任務重啟或遷移時,作業來不及或者根本無法完成savepoint,導致會有較長時間的狀態丟失。
為了解決這個問題,我們開發了最後一次cp作為sp的功能,並與產品平臺JRC進行了深度整合。基本過程是這樣的:在任務停止時,會將最後一次checkpoint持久化;在下一次任務啟動時,使用者可以選擇從最新cp恢復任務;在任務執行起來並完成一次cp後,會將上次持久化的cp刪除掉,釋放儲存空間。
6. 其他最佳化
HDFS最佳化:合併小檔案,降低RPC呼叫等。
- 讀取本地檔案時增加buffer用於緩衝提高讀寫效能。
- zk防抖:在網路抖動、計算節點負載壓力較大或zk服務短暫無響應時,會導致job manager / task manager與zk短暫斷開連線導致任務重啟,透過防抖最佳化可以避免任務重啟,提高穩定性。
- 任務區域性恢復:支援作業Failover時只恢復個別失敗的Task,從而避免整個任務重啟的巨大開銷,適用於可以容忍少量資料丟失的場景。
- 叢集多工排程隔離:把同一叢集中不同任務的運算元排程到不同taskManager中避免不同任務相互影響。
- 日誌增強:支援日誌分離、日誌級別動態配置等
- SQL擴充套件:視窗支援增量計算, 支援offset
- 智慧診斷:支援對作業大多數場景進行自動分析診斷,給出問題診斷結果和建議。
03
未來規劃
流批一體是今年比較火的一個方向,在一個引擎裡同時支援低延遲的流處理和高效能的批處理,可以做到架構統一,程式碼複用,降低使用者使用成本,同時避免流批割裂帶來的口徑不統一的問題。目前部分業務場景已經落地。
第二個方向就是提高穩定性。Flink任務恢復機制有較大的開銷,無論是全部重啟還是region重啟,都會對業務有一定的影響。如何在容器環境下進一步提高任務恢復的速度,減少對業務的影響,是我們努力的一個方向。
第三個方向是智慧運維,如何做到對任務的智慧診斷,根據作業執行情況進行引數自動調整、彈性伸縮等,這是我們目前正在進行中的工作。
第四個方向是AI的探索實現。AI也是目前比較火的一個方向,如何結合Flink更好地實現AI實時化、智慧化的場景也是我們將來要發力的一個方向。
今天的分享就到這裡,謝謝大家。
在文末分享、點贊、在看,給個3連擊唄~
分享嘉賓:
分享嘉賓:付海濤 京東 技術專家
編輯整理:蘇文進 怪獸充電
出品平臺:DataFunTalk