1. 首頁 > 網絡安全頻道 > 云安全

                    字節YARN 云原生化演進實踐

                    2022年12月19日 17:54:13   來源:字節跳動技術團隊

                      1. 演進背景

                      字節跳動(以下簡稱字節)內部離線業務具有龐大的規模,線上每天有數十萬節點運行,每天的任務數達到百萬量級,每天使用的資源量達到千萬核量級。在如此龐大的計算規模下,為了能夠高效地處理任務,提高資源流轉效率,調度系統發揮了非常重要的作用。

                      如上圖所示,我們可以清楚地看到,字節內部調度架構分為兩大塊 —— 離線調度系統和在線調度系統,離線調度系統主要負責離線資源管理和離線任務調度,在線調度系統主要負責在線資源管理和在線任務調度。

                      離線調度系統基于 YARN 實現,主要包括 Resource Manager(RM) 和 Node Manager(NM) 兩個組件,負責資源調度和容器運行時管理。字節內部在 YARN 的基礎上進行了很多功能豐富和優化工作,針對不同場景實現了不同的調度器,例如:Batch Scheduler,Gang Scheduler 等。

                      在線調度系統基于 Kubernetes 生態,進行了很多優化,支持字節內部多樣化的在線服務。

                      為了提高字節內部整體的資源利用率,我們也進行了混部技術的探索 。 主要思路是在在線的節點上同時部署 Kubelet 和 NM 服務,當在線節點比較空閑時可以及時將空閑資源出讓給離線業務使用,以此使得整個數據中心的資源利用率能夠得到比較大的提升。

                      但隨著公司內業務規模的持續發展 ,這一套系統也暴露出了一些短板 :

                      首先,在離線屬于兩套系統,一些重大活動場景需要通過運維方式進行在離線資源轉換,運維負擔繁重,轉換周期長;

                      其次,現在的混部架構只是在部分節點上同時部署了 NM 和 Kubelet 兩個 Agent,資源利用率仍有很大的提高空間;

                      最后,在離線是兩套割裂的系統,Quota 平臺、機器運維等都不能復用,大數據作業無法享受到云原生的各種好處,例如:資源池化、更好的單機隔離特性等。

                      綜上所述, 字節內部有三個核心訴求:

                      重大活動場景(春節 / 雙 11 等),在離線資源需要能夠高效、靈活地相互轉換;

                      整個數據中心的利用率需要得到更全面、充分的提升,進一步降本增效;

                      在離線資源共池,Quota 管控、調度、運行、機器運維統一。

                      為了實現上述訴求,我們進行了一些思考和探索。其中一種解決方案是:能不能讓離線作業直接遷移到 Kubernetes? 即:大數據生態下的各個計算引擎(包括:Spark、Flink 等)進行深度改造去適配 Kubernetes。在探索過程中發現這種方式有比較大的缺陷,主要有以下三點:

                      對計算引擎侵入較深,計算引擎側需要做大量改造才能支持原先在 YARN 的各種特性;

                      生產環境的作業(百萬級)非常多,如何從 YARN 平滑遷移到 Kubernetes 也是個比較大的問題;

                      特別地,部分比較古老的計算引擎,比如 MapReduce,目前處于 Maintain 狀態,已經無法進行大的改造來遷移。

                      基于以上思考,我們提出了一種全新的解決方案——Yodel。Yodel 的全稱是 YARN on Gödel(Gödel 是公司內部增強版 Kubernetes,它對 API Server、Gödel 調度器以及底層運行時都進行了增強),是字節跳動提出的 Hadoop YARN 云原生化演進實踐方案。通過 Yodel 我們將公司內的大數據業務(Spark、Flink 等)、訓練業務(Primus)平滑遷移到了 Kubernetes ,實現了在離線資源池統一,提升了整體資源利用率。

                      2. 解決方案

                      下面將從 Yodel 整體架構、Remote Godel Scheduler(RGS) 服務、Remote Kubelete Service(RKS) 服務、持久化服務、平滑遷移及重要優化六個方面來詳細介紹我們的解決方案。

                      2.1 Yodel 整體架構

                      Yodel 基于 YARN 實現,新增 ZK / ETCD / KV State Store、Remote Godel Scheduler 、Remote Kubelet Service 服務。ZK / ETCD / KV State Store 主要用于持久化存儲、Remote Godel Scheduler 維護資源請求并與 API Server 交互,將調度能力統一到 Godel Scheduler;Remote Kubelet Service 實現了 YARN NM 所有接口,對用戶和作業透明的前提下,把 NM 的 Container 管理能力平滑下沉到 Kubelet。

                      Yodel 整體架構圖

                      從上面的架構圖可以清楚看到 Yodel 的整體架構, 圖中藍色組件是進行了適配改造的組件,藍色中標紅的組件是新增組件,黃色組件是 Gödel 生態下的組件,關于新增組件:

                      ZK / ETCD / KV State Store:支持將集群元數據信息持久化到 ZK、 ETCD 和 KV 等持久化存儲,可以通過 API Server 方便地進行相關數據查詢和更新;

                      Remote Godel Scheduler:維護集群所有任務的資源請求,通過該服務將任務的資源請求轉化為 Pod 寫入 API Server,同時與 API Server 交互獲取已調度的 Pod,最終將調度能力下沉到底層的 Godel Scheduler;

                      Remote Kubelet Service:實現了原來 YARN 中 NM 的所有接口,例如:啟動容器、停止容器、獲取容器狀態的接口。通過這個服務容器啟動從 NM 切換到 Kubelet,最終將容器運行時的管理下沉到底層的 Kubelet。

                      下面介紹在 Yodel 架構下一個離線任務的提交和運行流程 :

                      用戶從開發機或任務托管平臺向集群提交一個任務;

                      當任務經過校驗后,Yodel RM 會新建一個 App 對象并持久化至 API Server;

                      Yodel RM 創建 AM Pod 并寫入 API Server,等待底層調度器調度;

                      Yodel RM 收到已經調度完成的 AM Pod 并進行相關轉化操作;

                      Yodel RM 將相關啟動信息豐富至 AM Pod 中并 Patch 至 API Server 由 Kubelet 拉起相關進程;

                      AM 啟動成功后,隨心跳主動向 Yodel RM 申請資源;

                      Yodel RM 收到任務的資源請求后,通過 RGS 服務將資源請求轉化為 Pod 對象或 PodGroup 對象并寫入到 API Server;

                      底層調度器 Watch 到相關對象后,按照一定策略進行調度,同時 Yodel RM 也會及時地 Watch 到已經調度的 Pod;

                      Yodel RM 會將已經調度的 Pod 轉化為 Container,隨心跳返回給對應的 AM;

                      AM 收到已經調度的 Container 后,會再跟 Yodel RM 進行交互,來啟動對應的容器;

                      Yodel RM 收到容器啟動請求后,通過 RKS 服務將容器啟動所需要的信息豐富到 Pod 對象里并 Patch 到 API Server。Kubelet Watch 到待啟動的 Pod 后,會進行這個 Pod 的啟動。

                      Yodel 架構 Pod 生命周期

                      上面講了 Yodel 架構下任務的啟動流程,下面我們來看一下對于一個 Pod 來說,它的生命周期是怎么樣的 ,核心流程如上圖所示:

                      首先,AM 啟動起來后會隨心跳申請資源;

                      Yodel RM 收到資源請求后,會基于該資源請求的資源量、優先級等創建一個 Pod 對象寫入 API Server。創建完成后,該 Pod 對象處于 Pending-Unscheduled 狀態,等待底層調度器進行調度;

                      底層調度器 Watch 到新創建的 Pod 后,根據一定策略進行調度,調度完成后會將調度結果寫入 API Server。寫入完成后,該 Pod 對象的狀態會變為 Pending-Scheduled 狀態;

                      Yodel RM Watch 到已經調度完成的 Pod 后會轉化為 Container,該 Pod 對象的狀態會變為 Allocated 狀態;

                      新分配的 Container 會隨心跳返回給 AM,Container 被對應 AM 拿走后,該 Pod 對象的狀態會變為 Acquired 狀態;

                      AM 獲取到容器后會與 Yodel RM 交互進行啟動操作;

                      Yodel RM 收到容器拉起請求后,會把容器啟動所需的信息填充到 Pod 對象中并 Patch 到 API Server ;

                      Kubelet Watch 到需要啟動的 Pod 后,會啟動相關進程,容器運行時由 Kubelet 維護。

                      2.2 Remote Godel Scheduler

                      下面來介紹調度模塊比較重要的一個服務 —— RGS 服務。由上圖可以看到,RGS 服務主要分為三大部分:

                      最上層是 Quota Manager 負責進行 Quota 管理: Quota Manager 部分在 YARN 基礎上進行了增強。在 YARN 中有隊列的概念,但隊列只支持一種資源類型。在 Yodel 中對此進行了擴展,一個隊列可以同時支持兩種類型的資源 —— Guaranteed Resource 和 Best-effort Resource。單隊列支持兩種資源類型后可以顯著簡化用戶的隊列管理成本,對用戶使用更友好。

                      Guaranteed Resource :穩定資源,使用 Guaranteed Resource 的容器一般情況下不會被搶占也不會被驅逐;

                      Best-effort Resource:混部資源, 是在線節點出讓的暫時空閑不用的資源,資源會隨著節點負載情況動態波動,使用 Best-effort Resource 的容器可能會被搶占或驅逐;

                      中間層是 Allocate Service 負責進行請求轉換和狀態維護: 主要包括四個子服務,Convert Reqeust To Pod Service 負責將任務的資源請求轉化為 Pod 對象并寫入 API Server;Convert Pod To Container Service 負責將已經調度的 Pod 轉化為 Container 并返回給 AM;Update Pod Status Service 負責及時更新 Pod 狀態并持久化至 API Server ;Delete Pod Service 負責在容器或任務結束時,及時刪除 API Server 中的相關對象。

                      最下層是 Remote Scheduler 負責進行調度和關鍵信息持久化。

                      通過上述各個服務的協調配合, Yodel 能夠實現:

                      100% 兼容 Hadoop 協議,用戶無需要做任何改動,可以像原來使用 YARN 一樣來使用 Yodel;

                      支持 GT 和 BE 兩種資源類型,方便上層用戶對平臺的使用。

                      2.3 Remote Kubelet Service

                      接下來介紹 RKS 服務。RKS 部署在 Yodel RM 內部,實現了 YARN NM 的所有接口,把 NM 的 Container 管理能力平滑下沉到 Kubelet。它主要由兩部分組成:

                      Patch Pod Service : 主要負責收到 AM 拉起請求后,將容器啟動所需的信息豐富到 Pod 對象中,這些信息包括:容器的 ENV 、 HDFS 自研列表、啟動命令等;

                      Pod Status Update Service : 該服務會及時從 API Server Watch Pod 的最新狀態,并將狀態返回給對應 AM。

                      此外,為了補齊 NM 上的運行體驗,底層以 daemonset 方式部署了一些其他服務。這些 daemonset 補齊了 NM 的能力,使得離線作業只需要升級 hadoop 依賴,不用做太多改動,就能讓容器運行在 Kubelet 上。這些服務包括:

                      LocalizationService : 用于下載 Pod 所需的 HDFS 資源;

                      Log Serving : 用于方便用戶查看 Pod 日志;

                      Shuffle Service : 主要有 Spark Shuffle Service 及 MR Shuffle Service,這些 Shuffle Service 是從 NM 的進程解耦出來的,單獨部署用于提供計算框架的 Shuffle 服務;

                      Metrics Collector : 用于收集離線 Pod 運行時的各維度監控信息;

                      Webshell : 方便用戶通過 Web 端進入到容器的 Shell,方便排查問題。

                      下面看一個容器是怎么運行在 Kubelet 上的:

                      改造了 NM Client SDK,使 AM 調用 startContainer 時能直連 RKS;

                      RKS 收到啟動請求后,會把 containerLaunch 上下文等信息寫入到 Pod 并 Patch 到 API Server;

                      Kubelet Watch 到離線 Pod 后,會通過本機的 LocalizationService 下載 Pod 對應的 HDFS 資源;

                      下載完成后, Kubelet 通過 Containerd 把對應的 HDFS 資源掛載到容器的 Pod 里,之后通過 Containerd 啟動 Pod;

                      啟動完成后,Kubelet 會把 Pod 的狀態更新回 API Server;

                      RKS watch 到 Pod 狀態變化后,同步更新內存中的 Container 狀態,之后等待 AM 心跳時同步 Container 最新狀態。

                      2.4 持久化服務

                      YARN 架構是通過 ZKRMStateStore 將元數據信息持久化到 ZooKeeper,而 Yodel 架構,我們自己實現了一個 KVStateStore 存儲元數據到 API Server,存儲的元數據包括 MetaData,Queue,Application,Appattempt 和 Pod,F在線上的一個 API Server 可以支持存儲 300 queue,2w 個 application,10w 個 app attempt,以及支持 30W 離線 Pod 同時運行。

                      MetaData:集群元數據信息、集群默認配置等;

                      Queue (~300 / cluster) :隊列 Quota、ACL 信息等;

                      Application(~2W / cluster) :Name、User、State 等;

                      AppAttempt(~10W / cluster) :Name、User、State 等;

                      Pod (~30W / cluster) :State、Annotation、ENV、HDFS 自研列表、啟動命令等。

                      2.5 平滑遷移

                      字節內每天運行著百萬量級的任務,如何平滑地把作業從 YARN 架構遷移到 Yodel 架構是一個很大的挑戰,整體上我們是通過 ResLake 來完成的,首先介紹幾個關鍵組件:

                      WorkFlow Hosting:作業托管平臺,負責進行作業提交;

                      ResLake:是 RM Proxy,可以根據一定策略把作業路由到不同集群;

                      Quota Platform:用于同步隊列的 Quota 信息;

                      AutoMigration:負責從 YARN 集群下線節點,搬遷到 Yodel 集群上。

                      ResLake 在 YARN 集群和 Yodel 集群上有同名的隊列,如上圖中的 root.queueA 和 root.queueB,這兩個集群上的隊列有著相同的元數據信息。AutoMigration 服務會不斷地從 YARN 搬遷節點到 Yodel 集群,搬遷信息會同步給 Quota Platform,Quota Platform 會進一步將隊列 Quota 信息同步給 Reslake。作業托管平臺提交作業到 ResLake 時,ResLake 會根據 YARN/Yodel 上隊列的 Quota 信息,決定作業是提交到 YARN 集群還是 Yodel 集群。隨著機器不斷地往 Yodel 搬遷,最終作業也平滑遷移到了 Yodel 集群上。

                      2.6 重要優化

                      在 Yodel 架構升級上線過程中,也遇到了很多問題,我們也做了非常多的優化,主要包括性能優化和運行優化。

                      2.6.1 性能優化

                      Recover 階段異步恢復 Pod 狀態降低切主時間(秒級):起初為了確保切主后集群、隊列和任務的各維度統計信息準確,采用同步方式恢復 Pod,但上線時發現恢復過程非常耗時。為此通過優化,在確保各維度信息統計準確的前提下異步恢復 Pod 狀態,將切主時間縮短到秒級;

                      異步多線程操作 Pod 以提高調度吞吐(~2K / s):通過異步多線程方式將已經調度 Pod 轉化為 Container 后,調度吞吐得到顯著提升,目前調度吞吐可以達到每秒 2000 個 Pod;

                      PodName 散列優化助力底層存儲寫延遲降低為原來的 1 / 100(百分之一) : 因 API Server 底層采用基于 range 的 KV 存儲,若 PodName 有序會頻繁產生分區裂變,導致 API Server 的相關處理延遲顯著增加。通過將 PodName 進行散列優化,將 Pod 打散存儲在不同的分區中,底層存儲寫延遲下降 100 倍;

                      與 API Server 交互增強,Java Fabric8 Kubernetes Client 優化:

                      支持指數退讓重試,增強 API Server 故障容錯;

                      List 操作默認添加 ResourceVersion 參數,避免擊穿到底層存儲;

                      將 Informer Resync 設置為 0,避免頻繁內存拷貝造成 OOM。

                      2.6.2 運行優化

                      AM 容器運行在單獨資源池,獨立優先級不可搶占:對于使用 BE 資源的容器有被搶占或驅逐的風險,而 AM 作為任務的 Master 一旦失敗就會導致整個任務失敗。為了避免此問題,將 AM 容器運行在單獨的資源池,確保 AM 可以穩定運行避免任務失敗;

                      支持鏡像本地化約束,平均拉起速度提升約 1000 倍:一些離線任務的鏡像比較大,在容器啟動時拉取鏡像會花費較多時間,進而導致啟動時間變長。為了解決該問題,支持了鏡像本地化約束,讓容器可以盡量調度到有鏡像的節點,該功能上線后容器平均拉起速度提升 1000 倍;

                      支持雙棧節點和 v6 only 節點在單集群混跑:通過將雙棧節點和 v6 only 節點混跑在同一個集群中顯著降低了運維成本,同時也有利于資源利用率提升;

                      Shuffle 數據寫遠程,避免打爆本地磁盤:shuffle 數據通常較大很容易將本地磁盤打滿,將 shuffle 數據寫遠程后,可以避免因本地磁盤打滿而導致任務運行異常;

                      大量引入 SSD 和 Nvme 磁盤,加速作業運行。

                      3. 上線收益

                      Yodel 架構已經在字節內部上線,上線后帶來了如下收益:

                      高效資源切換:實現了 2022 元旦/春節 約 50 萬核離線資源分鐘級出讓,顯著提高了在離線資源轉化效率,為重大活動場景下的資源切換提供了堅實的技術支撐;

                      利用率提升:NM 和周邊單機組件下線,降低 Overhead,帶來單機 2% 利用率提升;

                      在離線統一:在離線資源全量共池,Quota 管控、調度、運行、機器運維統一。

                      4. 未來規劃

                      RGS & RKS 部署云原生化

                      接入服務發現

                      支持容器化部署

                      可彈性擴展

                      開源 Yodel 回饋社區

                      文章內容僅供閱讀,不構成投資建議,請謹慎對待。投資者據此操作,風險自擔。

                    [編號: ]
                    分享到微信

                    即時

                    新聞

                    騰訊前三季研發投入454.75億元 前沿科技加速落地服務

                    11月16日,騰訊控股(HK.00700)發布2022年Q3財報,騰訊實現營業收入1400.93億元,非國際會計準則凈利潤(Non-IFRS)322.54億元,同比恢復增長,多個主營業務板塊收入亦呈現環比企穩跡象。

                    企業IT

                    今日影像,今日推送!星圖地球今日影像正式發布,開

                    每一次火箭升空、衛星發射都能引起全國人民的關注,那你可曾想過,有朝一日每個人都能召喚衛星為自己服務?

                    研究

                    IDC發布中國數字政府IT安全軟硬件市場份額報告

                    IDC《中國數字政府IT安全硬件市場份額,2021》報告顯示,中國數字政府IT安全硬件市場的規模達到64.9億元人民幣,同比增長31.5%。

                    老师穿包臀裙和我啪啪