位元組跳動 Flink 大規模雲原生化實踐

ApacheFlink發表於2023-04-06

摘要:本文整理自位元組跳動基礎架構工程師劉暢,在 Flink Forward Asia 2022 生產實踐專場的分享。本篇主要從四個方向展開介紹。

  1. 背景介紹
  2. 解決方案
  3. 生產實踐
  4. 未來展望

點選檢視直播回放和演講 PPT

一、背景介紹

1.1 資源管理演進

1

位元組跳動的大資料資源管理架構,以及 Flink 的部署演進,大致可以分為三個階段。

  • 第一階段,完全基於 YARN 的離線資源管理。大規模使用 YARN 管理的大資料叢集,有效提升了 Flink 的資源使用率,並降低了資源運營、運維等方面的成本。於此同時,針對 Flink 的特性,對 YARN 做了大量定製研發,如支援 Gang 排程等。在此階段,Flink 叢集已經達到了相當大的規模。
  • 第二階段,離線資源混部階段。透過構建 YARN 和 K8s 混合部署叢集,進一步提升線上和離線的整體資源使用率。並透過混部技術方案,使叢集/單機資源利用率都得到顯著提升。更高的單機利用率,意味著需要更完整的隔離手段,因此逐步開始推進 Flink 的容器化部署並獲得了相應成效。
  • 第三階段,徹底的雲原生化部署。線上負載和離線負載不再使用不同的架構進行管理,真正實現了技術棧統一和資源池統一,Flink 的雲原生化也在逐步構建完善。

1.2 雲原生的優勢

2

雲原生化幾乎是業界一致的發展趨勢,那麼為什麼要選擇雲原生 K8s 作為統一的資源管理底座呢?

  • 高效運維。K8s 提供敏捷的負載建立和管理,無論是線上負載還是 Flink 大資料負載,都能夠便捷實現持續開發、整合和部署。
  • 資源共池。統一的雲原生底座減少了基礎設施開銷,也進一步提升了資源流轉效率。在春節、雙 11 等大型活動場景下,在離線資源可以高效、靈活地相互轉換;在資源利用率方面,整個資料中心的利用率可以得到更全面、充分的提升,降本增效。
  • 生態繁榮。K8s 擁有幾乎最活躍的生態圈,它透過提供標準化的介面定義,促進了各個層次的生態發展,無論是基礎運維設施、上層應用管理還是底層的網路、儲存等管理中都有非常多的可選方案,Flink 的雲原生化也為未來的方案使用提供了便利。

1.3 Flink 業務規模

3

位元組跳動擁有業界領先的 Flink 業務規模,目前 Flink 每天執行的作業數有數百萬個,佔有資源量數百萬核,總的叢集規模節點也達到了上萬臺,如此大規模的 Flink 負載意味著徹底的 Flink 雲原生化並不是一件輕鬆的事情,關於關鍵問題的思考請瀏覽下面的內容。

1.4 關鍵問題

4

Flink 的大規模雲原生化有幾個關鍵問題需要思考。

  • Flink 作業的部署管理,是 Standalone 的靜態部署還是 K8s Native 動態部署,是否使用 Operator?
  • 在 K8s 上如何實現 Flink 作業的租戶級別資源管控,在作業提交時進行管控,還是在 Pod 建立時進行管控?
  • 如何支援 Flink 的排程需求?在 Flink 作業提交或重啟時,大量的 Pod 建立是否引起排程瓶頸?
  • 大規模作業的架構遷移,周邊能力如何建設,需要另起爐灶,還是儘可能複用?

二、解決方案

2.1 部署方案

關鍵問題:Flink 如何在 K8s 上執行?

第一種,Standalone 部署模式。這種模式下,Flink 作業依賴的所有資源,都由作業提交使用者發起建立。其原理和使用比較簡單,但存在資源利用效率低,Failover 成本高等問題。

第二種,Kubernetes Native 部署模式。這是目前社群比較推薦的部署模式,Jobmanager 可以根據作業的需求自主建立 Taskmanager Pod,但完全的 Native 部署模式依然存在一些問題:

  • 沒有完整的生命週期狀態描述和管理;
  • 批排程對接成本高;
  • 缺少全域性視角,不容易進行一些全域性的調控。

除此之外,Flink 部署也可以搭配使用 Operator,目前 Operator 通常針對負載單獨定製,未來進行多種負載混部時,就需要部署多套 Operator,這無疑加大了運維上的成本。

5

為了更方便的管理 Flink 等大資料負載,位元組自研了一個統一的大資料 Operator Arcee。如圖所示,Arcee 執行在 K8s 底座之上,向上可以同時支援 Flink 的流式和批式作業。Arcee 的核心能力主要包括作業生命週期管理、作業資源管理和一些引擎的定製功能等。

6

Arcee 的核心設計思路是,兩級作業管理。Arcee 借鑑了 YARN 的兩級管理模式,即中心管理服務 AM,主要負責建立和維護大資料作業,再由 AM 建立維護計算 Worker。對應到 Flink 作業中就是由 Arcee 建立 JM,JM 建立所需的 TM。這種管理模式,一方面可以有效管理和表達大資料作業狀態,定製作業管理策略。另一方面也可以確保計算引擎對計算作業執行有充分的掌握能力,有能力按需調整資源使用。

7

如圖所示,Arcee Operator 內部包含了六個模組:

  • Arcee CRD,Arcee 定義了 ArceeApplication 和 ArceeCommand 兩種資源型別;ArceeApplication 用於描述具體的作業,ArceeCommand 描述用於作業的操作;
  • Webhook 模組,主要用於 Application / Pod 的配置注入和校驗;
  • Application Manager 負責作業的生命週期管理;
  • PodSetManager 是作業資源管理;
  • EngineManager 是引擎管理,用於實現一些引擎定製能力;
  • Schedulermanager 是排程器對接層,用於完成 Flink 等大資料作業與批排程器的對接。

基於這幅圖,作業完整的提交流程是當上層發起 Flink 作業提交時,作業提交平臺呼叫 Flink Client,並填上所需的引數向 K8s 提交作業。在 Arcee 模式下,Flink Client 使用內建的 Arcee Client 建立 Flink Arceeapplication,由 Webhook 預處理後提交到 Apiserver。接下來,由 Arcee Controller 收到 Application 的建立事件,Arcee applicationManager 生成對應的作業狀態,並根據 Application 內的描述建立 JM,並由 JM 根據 Job 建立所需的 TM,Arcee 會持續監聽所有 TM 的建立,同樣也會進行相關配置的注入。Application 內 JM、TM 的所有 Pod 都會維護在 Arcee 的 PodsetManager 中,用於資源使用統計,並向其他模組提供相關資訊。

8

以上可以發現,Flink 使用 Arcee 的部署模式和 K8s Native 部署模式有相似之處。Flink on Arcee 在一定程度上可以認為是 Flink Native 部署模式的改進。具體的區別如下:

Jobmanager 的建立和生命週期管理,由 JobManager Development 負責完成。JM 啟動後,Resource Manager 模組可以直接和 K8s API Server 進行通訊,完成 TaskManager Pod 的建立和銷燬工作。在這種架構下,對於 K8s 來說,JM 和 TM 幾乎是完全獨立兩部分資源。

9

Flink on Arcee 的架構有如下不同:

  • Flink Client 中的 K8s Client 替換成 Arcee Client;
  • 負責管理 JM 負載的元件由 Controller Manager 變成 Arcee Operator;
  • 負責拉起 Jobmanager 的 Deployment 變成了 Arcee Application;
  • JM 和 TM 從各自獨立變成擁有統一的 Application 進行維護。

10

Arcee 提供的具體功能

作業生命週期管理:Arcee 提供了一個細粒度的作業狀態機叫做作業資源狀態。透過作業資源狀態,可以知道作業的資源建立處於什麼階段,此外也可以反映作業的執行終態及 Flink 的內部狀態。Arcee 也提供了多種 Failover 策略,使用者可以根據狀態定製重啟策略,目前可以支援 Never、Always、Onfailure 多種重啟策略,支援配置最大重啟次數,支援底層異常失敗探查。

11

排程遮蔽:對於 Flink 大資料作業來說,往往需要搭配使用批排程器。批排程器與普通的排程器不同的點在於,批排程器使用的時候 需要額外建立批排程單元,並持續觀察批排程端元的狀態。目前,業界沒有給出一個標準的批排程處理模式。Arcee 遮蔽了底層排程細節,計算引擎自身不需要關心排程器的接入方式,Arcee 的作業資源管理模組可以完成排程對接。

2.2 資源管理方案

關鍵問題:如何實現 Flink 作業的租戶資源管控?如何實現高效能的批排程?

12

租戶的資源管控最核心的能力是叢集資源的公平分配。此外還需要提供租戶內的高/低優作業排隊與搶佔。Flink 的大資料負載和線上負載的不同點在於線上負載中 Pod 的建立幾乎完全是使用者發起的,建立所需資源量也是建立前明確的。但可動態調整的大資料負載不同,一是 Pod 的建立時間不確定,二是所需資源量不確定。這也就需要提前為使用者劃分資源並進行管控,防止某個作業佔滿叢集。

除此之外,批排程能力也是 Flink 雲原生需要解決的重要問題。首先,Flink 流式作業通常需要 All-or-Nothing 的排程能力,否則可能會出現資源死鎖。其次,大量的 Pod 建立要求排程器具備很高的排程吞吐能力。最後,位元組跳動內部,Flink 過去在 YARN 上有很多排程定製能力,如真實負載平均,全域性黑名單等。這些都是經過實踐能有效最佳化 Flink 執行的策略,遷移至 K8s 後依然保留了下來。

13

為了解決租戶資源管控問題和批排程相關問題,透過研發一個基於雲原生的高效能資源管理排程器—— GRO 排程器,實現叢集資源的管控。

GRO 在 K8s 上增加了“佇列”和“作業”的定義,其中佇列對應了 Queue CRD,是 Quota 資源配額的抽象;作業對應了 PodGroup CRD,描述了一個“作業”排程單元,標識多個 Pod 屬於同一個集合。另外 GRO 還提供了一個作業資訊統計定義-OpJob CRD,用於提供細粒度的作業資源計量及狀態資訊。

14

在問題介紹部分提到了 Flink 負載的兩個特點—— Pod 建立時間不確定、所需資源量不確定。在這兩個特點下,排程器是最適合做租戶管控的元件。

GRO Scheduler 參考 YARN 等大資料排程器,在 Pod 放置的基礎上增加了 Quota 管控。首先,GRO 會透過所有佇列的 Min(保障資源)、Max(資源上限)屬性將叢集資源公平地分配給各個佇列。接下來,再根據不同排程策略(優先順序排程、Gang 排程等),將佇列資源分配給佇列內的各個排程單元,再進一步分配給作業內的各 Pod,透過以上排程流程就可以在 K8s 上實現較細緻的租戶資源管控。

排程器的本質工作是資源排程,GRO Scheduler 具備 Flink 負載所需要的批排程能力。首先,GRO 支援 Gang 排程,能夠提供 All-or-Nothing 排程語義,並在此基礎上實現了排程快速失敗功能,用於防止 Flink 作業長時間等待。其次,GRO 具備高排程吞吐能力,在支援複雜排程策略的前提下,排程吞吐效能仍然可以達到每秒上千 Pod。最後,GRO 擁有豐富的放置能力。除了支援大部分原生功能外,還支援真實負載平均、GPU 共享、微拓撲排程等大資料場景的高階策略。

2.3 平臺方案

關鍵問題:不同架構下作業&佇列管理如何切換?

15

無論底層使用的是什麼資源管理架構,作業和佇列的基本管理操作在使用者和上層平臺看來大體是一致的。主要包括作業查詢/ Kill,佇列的建立/擴縮容等。此外,作業的 Webshell 登入、日誌查詢等周邊服務,在不同架構下使用不同的元件實現對應功能。但一些依賴上層後設資料實現的功能如許可權控制等,在架構遷移前後也需要對應實現。那麼就需要基於新架構,考慮將上層平臺進行重新接入還是複用原有架構的資料和能力,打平前後接入差異?顯然,如果能打平差異,做到上層業務平臺的無感接入是最優的方案。

16

為了實現前後架構基礎管理和周邊能力的打平,構建了一套前後複用的資管架構平臺方案——Megatron 離線排程使用者平臺,主要是為了方便多業務平臺查詢接入,緩解底層 YARN 的查詢壓力。以上的定位和功能設計使 Megatron 成為最適合做架構遮蔽的平臺。不僅為多種業務平臺提供統一的介面,也具備較完整的作業和佇列管理能力。其中,主要功能有作業同步、佇列管理、資料查詢、許可權管控等。因此,Megatron 針對新的雲原生底座進行了適配,成為了一個為 YARN 和 Kubernetes 同時提供簡單便捷且統一的離線計算資源及作業管理平臺。

三、生產實踐

17

Flink 雲原生化在位元組跳動的生產實踐情況。目前,流式通道任務,Streaming SQL,Streaming Java 等流式任務,都已完成雲原生構架的適配。包括抖音、電商、推薦在內的幾乎所有 Flink 業務,都已實現了新架構的接入。此外,這一整套架構也已實現了產品化的程式。

18

在作業遷移方面的實踐,對於上層使用者來說,作業的架構遷移看起來就是一次佇列切換。作業提交服務會透過 Megatron 查詢佇列的屬性,並自動生成對應的提交引數。Arcee 層面也儘可能的為使用者遮蔽環境因素,此外 Flink 引擎在前後架構適配上,也做了非常多的改造工作,包括 Classloader 的差異相容等。

為了加快公司內架構遷移的進展,構建了一套自動遷移流程。透過定期梳理待遷移的作業列表,並按照一定頻率觸發作業的佇列切換重啟,Quota 平臺會相應的進行遷移前佇列的縮容和後續佇列的持續擴容,機器就會從老架構叢集搬遷至新架構叢集。在實際的遷移過程中,自動化遷移可以達到接近 1000 /天的作業遷移速度。

19

在 Flink on K8s 的環境中,日誌和監控指標也是非常重要的,它可以幫助我們觀察整個叢集、容器、任務的執行情況,根據日誌和監控快速定位問題並及時處理。所以也在 Flink 雲原生化的過程中逐步構建了一套 Trace 體系。Flink 提供了業務指標,單機的 Metrics Collector 元件提供了物理機指標和容器指標。在日誌方面,透過每個 Node 上執行的 Log Agent 採集指定路徑的日誌自動上傳至日誌平臺進行解析查詢。所有的指標和日誌,都可以基於 Megatron 的平臺化實時查詢,也提供了具體的資料表,使用者可以根據需求進行更高階的查詢,比如製作報表,作業調優,作業異常發現等。

20

在上量過程中,除了能力的構建也進行了生產上的最佳化。可以分為針對控制面的管控最佳化和 Flink 執行的執行最佳化。在管控最佳化方面,對 K8s Client 進行了拆分和引數調優,避免不同的 Apiserver 操作相互干擾。使用非同步多執行緒處理方式提升系統本身作業的處理吞吐,透過最佳化與 Apiserver 的互動頻率,儘可能減少不必要的資源操作。

在壓測中,我們發現與 Apiserver 的互動是作業處理流程中開銷最大的一環。透過互動最佳化,一方面減小了 Apiserver 的壓力,另一方面也減少了 Apiserver 互動帶來的處理開銷。在執行最佳化方面,構建起了 Region 級別的唯一性檢測,用來避免 Flink 作業的雙跑。在遠端資源下載方面,透過使用 P2P 進行下載加速,此外還參考 YARN 實現了資源的共享複用,減輕整體的下載壓力。雲原生的部署方案使得 Flink 可以使用更高階的隔離能力,透過引入 Sidecar 的部署模式,將資源消耗較大的元件整合在 Flink Pod 中,用來避免這些元件對機器上的其他作業產生影響。

四、未來展望

21

未來的工作將主要圍繞三個方面。

多雲架構的設計落地和基於多雲的容災能力構建;

資源的彈性混部,同時進行資源調優,在保障 Flink 執行質量的同時進一步提升資源利用率。

效能和叢集規模上的持續提升,未來將不斷提升 Controller、排程器等的處理能力,用於支援像容災類的極高吞吐要求場景,並支援更大規模的叢集。

點選檢視直播回放和演講 PPT


更多內容


活動推薦

阿里雲基於 Apache Flink 構建的企業級產品-實時計算Flink版現開啟活動:
99 元試用 實時計算Flink版(包年包月、10CU)即有機會獲得 Flink 獨家定製衛衣;另包 3 個月及以上還有 85 折優惠!
瞭解活動詳情:https://www.aliyun.com/product/bigdata/sc

image.png

相關文章