谷歌每年節省上億美金,資源利用率高達60%,用的技術有多厲害!


作者

作者田奇,騰訊高級工程師,專注大規模在離線混部,分布式資源管理調度,熟悉Kubernetes,關注雲原生大數據、AI。

導語

什么是在離線混部

隨着微服務、大數據、人工智能的不斷發展,為了滿足業務需求,企業的 IT 環境通常運行兩大類服務,一類是在線服務,一類是離線作業

在線服務:往往長時間運行,服務流量存在周期特性,整體資源使用率不高,但是對服務 SLA 卻有着極高的要求,如網頁搜索服務、電商交易服務等。

離線作業:往往是資源密集型服務,但其可以容忍較高的時延、失敗任務重啟,如大數據分析服務、機器學習訓練服務等。

這兩種類型的服務負載在分時復用、資源互補上存在極大的優化空間,使得它成為混部的首選場景,所謂在離線混部,指的就是將離線作業和在線服務部署到同一個節點,以此來提高資源利用率,減少企業對與日俱增的離線計算資源的成本開支

在離線混部價值

資源利用率提升

據 Gartner 統計,全球數據中心平均使用率不足15%,每年會有巨大的資源浪費。

造成資源效率低下的原因,主要是以下幾點:

  1. 業務流量周期性,對於在線服務,為了保證其流量高峰期的業務 SLA,往往按照最高峰值評估資源。比如外賣業務,峰值期(吃飯時間)可能需要8 核 CPU,但是在低峰期(夜晚),可能就不消耗資源,導致大部分時間段資源利用率都很低,造成浪費。
  2. 集群資源碎片,所謂資源碎片,指的是服務器還有一定的靜態資源沒有被分配,但是由於此時各個維度的資源(如 CPU 和 ram )不均衡,導致沒有辦法再繼續分配資源。由於當前主流的資源調度框架,都會采用靜態資源分配算法來分配資源,最終都會造成資源碎片,從而無法有效利用資源。
  3. 在離線機房隔離,資源池划分粒度太粗,有些企業會將在線機房(主要部署在線服務如 Web)、離線機房(主要運行離線集群如 Hadoop)完全隔離開,在這么粗的粒度划分下,在線機房有大量資源閑置,也無法被離線服務利用,反之亦然,離線機房空閑的時候,在線業務也無法充分利用,無法實現不同 IDC 之間資源池的互通。

通過在離線混部,可以充分利用節點的空閑資源,從而提高資源利用率。

成本優化

在離線混部當前在各大中型互聯網公司等都有落地,通過混部提升資源利用率,可以獲得可觀的成本節省,獲得規模效應下的巨大經濟價值

下面可以做一個簡單的計算分析,我們提升20%的資源利用率,可以大致節省的預算:

假設我們當前所有的機器有10w 核 CPU,平均每台機器的資源使用率是20%, 那么 0.2 * 10w = 2w 核,在業務規模不變的情況下,假設資源平均使用率提高到40%,我們只需要5w 核就可以滿足業務需求,假設 CPU 的平均價格是 300元/核/年,就可以節省 5w * 300= 1500w 元/年。

對於有成本控制訴求的企業,在離線混部是降本增效的首選,比如谷歌已經將所有業務混合部署在 Borg(Kubernetes 的前身)系統中,其資源利用率可以達到60%,每年可以節省上億美金

挑戰

調度保障

資源復用

傳統模式的 Kubernetes 按照業務申請的 request 資源量進行靜態調度,如果在線和離線業務都按照 request 進行調度,離線業務先調度,占滿了節點的 request 資源,那么在線業務就無法調度了,同理,如果在線業務先調度並占滿了節點 request 資源,離線業務就沒法調度了,傳統模式的調度器將沒有辦法進行在線業務的資源復用。

傳統的資源復用方式,往往會采取分時復用,就是在固定的時間點跑離線業務,比如凌晨以后,就開始調度運行離線業務,在白天開始調度在線業務。這種模式下的資源復用,往往時間粒度過粗,雖然可以在一小段時間內復用在線資源,但是有比較嚴格的時間限制。

另一種是資源預留,將一個機器的資源整體划分為在線資源、離線資源以及在離線共享資源,該方式采用了靜態划分的方法,將整機資源進行了划分,無法進行彈性復用,而是只能將在線業務和離線業務的資源進行提前預留。雖然通過部署離線業務能夠一定程度的提高資源利用率,但是復用不夠充分,並且需要資源規格大的機器才能將資源進行靜態划分。

因此,要想高效的、自動化的進行細粒度的資源分時復用,就必須擁有及時准確的資源預測手段、快速響應資源變化的能力,以及一套可以在資源水位變化的時候進行的服務保障措施。

調度增強

由於在線業務和離線業務在工作模式上的差異,社區往往采用不同的調度器進行調度。

混部場景下,在線調度器和離線調度器同時部署在集群中,當資源比較緊張的時候,調度器會發生資源沖突,只能重試,此時調度器的吞吐量和調度性能會受到較大影響,最終影響調度的 SLA。

同時,大規模批量調度場景下,原生的 Kubernetes 是無法支持的,它只支持在線業務的調度。

資源保障

在線業務和離線業務本來屬於不同的工作類型,將這兩種負載部署在同一個節點上,會出現資源干擾,所謂資源干擾,就是當資源緊張或者流量突發的時候,在線業務在資源使用上會受到離線業務的干擾。在離線混部最重要的目標,就是在提高單機資源利用率的同時,保障在線和離線業務的服務 SLA

  1. 針對在線業務,需要保證其在業務在流量高峰時期與沒有混部之前一樣,不能產生較大的干擾,需要將其干擾率降低到5%以內。
  2. 針對離線業務,不能因為優先級不如在線業務,就一直處於飢餓或者頻繁驅逐狀態,影響離線業務總的運行時間和 SLA。

資源隔離

容器的本質是一個受限制的進程,進程之間通過 namespace 做隔離,Cgroup 做資源限制,在雲原生時代,所有的業務負載都是通過容器來控制隔離和資源限制。在離線混部場景下,雖然可以通過 Cgroup 來限制在線和離線業務的資源使用,但是當前的原生 Cgroup 在資源超售和在離線場景下,CPU、內存、網絡和磁盤 IO 都存在不同的挑戰。

在 CPU 方面,給創建的 Pod 指定 Limit,就可以通過 Cgroup quota 限制容器的最大資源使用量,采用 CPU share 權重來划分不同應用的 CPU 權重,但是這種手段在資源不緊張的時候還可以,一旦在線服務有流量突發,此時離線業務是很難立即退出運行的核心的,從而引發在線業務的 SLO 抖動。

為了保證在線服務穩定性,普遍做法是進行 CPU 綁核,將在線服務綁定在某個邏輯核心上,避免其他業務占用。

但是此時會出現兩個問題,一方面是 CPU 核心獨占,資源利用不充足的問題,因為一旦一個核心被獨占, CPU 就無法充分利用了,而混部的目的就是為了壓榨 CPU 的資源,讓其能夠充分運行;

另一方面,綁核以后,對於有並行計算要求的服務,不管是在線還是離線,都會受到並行度的影響,比如原來雖然限制最多4個核心,但是由於不綁核,服務其實可以並行的使用所有的 CPU ,並行度可以大大提高,但是一旦將服務綁定在4個 CPU 上,那么其並行度就最大是4了。

以上場景中的矛盾相信很多落地在離線混部的廠家都遇到過。

在內存方面,離線業務往往會讀取大量文件數據,導致操作系統會做 page cache,而原生操作系統對page cache的管理是全局的,不是容器維度的,容器在 cgroup 的資源限制機制下,往往存在 page cache 無法及時釋放的問題,導致其他容器在內存的分配上出現抖動,甚至存在 page cache 一直被另一個 cgroup 占用,無法清理 cgroup 的問題,在離線混部中,如果是離線業務也使用了 page cache,那么此時離線業務的資源可能無法進行調整和壓制成功的,就在於 page cache 沒有釋放。

資源干擾

超線程技術其實是現代 CPU 架構中非常常見的一種硬件虛擬化手段。

簡單來說,現代 CPU 基本都是 Numa 架構的,每個 Numa 節點上會有 Socket,Socket 中存在物理核 Core,物理核上還可以開啟超線程技術,讓操作系統看到多個 CPU 邏輯,我們平常用 top 命令看到的 CPU ,就是指的邏輯 CPU ,當沒有開啟超線程的時候,該邏輯 CPU 就是物理核心,但是如果開啟超線程,該邏輯 CPU 可能就是物理核心上虛擬出來的一個邏輯 CPU 。

比如,如果進行在離線混部,在線業務和離線業務被調度到了同一個物理核心的不同邏輯核上運行,此時就會產生干擾。

TKE 方案

TKE 針對騰訊內部自研業務上雲的場景,設計和實現了混部相關方案。

調度保障

我們采取混部節點自動上報擴展的離線資源,離線服務通過離線 Cgroup 大框隔離的方式來保證資源的彈性復用和回收。

在調度增強方面,多調度器共享狀態調度的模式,第一是解決在線資源的復用調度問題,第二是解決調度沖突、調度性能、可擴展性和可靠性。

資源復用

上文講到,傳統模式的 Kubernetes 按照業務申請的 request 資源量進行靜態調度,如果在線和離線業務都按照 request 進行調度,離線業務先調度,占滿了節點的 request 資源,那么在線業務就無法調度了。同理,如果在線業務先調度,離線業務就沒法調度了,傳統模式的調度器將沒有辦法進行在線業務的資源復用。

首先,在資源復用的方式上,TKE 將空閑的在線資源進行精准預測,並通過擴展資源的方式,暴露給離線調度器,從而讓離線調度器可以看到有多少離線資源是可以復用的,然后進行調度。

  1. 針對 request 資源可以修改的離線負載,為了讓業務不感知修改資源邏輯,采用 webhook 動態修改其 resource 中的 CPU 等原生資源表達,轉變為 extend 資源表達,轉換為 besteffort 類型的 Pod,供離線調度器調度計算使用。
  2. 針對 best-effort 類型的離線負載,我們根據混部節點上報的擴展離線資源,彈性的復用在線資源,該擴展資源隨着節點的負載水位實時變更,上文中資源沖突復用已經講述具體的方案。
  3. 針對 request 資源不可修改的離線負載(如 driver pod),此時會按照真實的 request 進行調度,那么就有可能和在線調度器發生沖突,因為在混部集群中,整個集群的 request 資源都往往已經被在線業務裝箱滿了。

其次,資源復用以后,需要能夠有一層限制,限制離線負載不能過度使用宿主機的資源;在底層資源限制上,針對在線和離線業務,分別限制其在不同的 Cgroup 層級上:

  1. 針對在線業務,還是正常的設置其資源需求,按照其 request 資源進行調度,最終按照 Kubernetes 原生的 Cgroup QoS 管理方式設置其資源限制;
  2. 針對離線業務中的 worker 等資源密集負載,將所有的離線 Pod 限制在一個 Cgroup 父層級構造的資源池內,也就是離線大框,該方案的優點在於既能夠讓離線業務充分使用到在線空閑資源,但是在在線資源回收的時候,又可以限制住所有的離線任務,從而保證在線服務的穩定性。

為什么不直接將離線任務當做 Kubernetes 原生的 best effort 處理呢

原因在於 Kubernetes 機制下的 best effort 類型負載,在 Cgroup 這一層是不設置資源限制的,一旦 Pod 有異常使用資源的情況,將會引發在線資源被搶占和內存擠爆的風險,所以必須要用一個有限制的上層的 Cgroup 來進行限制。

由於 Kubernetes 原生的 Cgroup 管理器,並不支持自定義 Cgroup 層級和更新資源,因此業界往往會入侵 kubelet 代碼,修改 kubelet 的 Cgroup 管理器,但是 TKE 全棧式混部對 Kubernetes 是零侵入的,通過采用 CRI 劫持的方式,做到對 Kubernetes Quality of Service 中底層 Cgroup 的修改但是卻不用修改 Kubernetes代碼,這對於客戶來講是一大亮點。

你不需要做任何處理就可以享受到極致的資源提升效果,同時 Kubernetes 的特性和社區完全兼容,我們可以做到單個節點粒度的混部框架自動上下線,幫助你再需要的時候進行混部操作。

在資源的預測和負載處理上,TKE 采用指數衰減滑動窗口算法,達到快速感應資源上升,慢速感應資源下降的目的,做到自動化,細粒度的分時復用目標;之所以需要快速感應到資源上升,是因為在線服務負載如果有上升,一般都是比較短暫的,此時需要快速感知,從而快速做出資源回收和離線退位。

而在負載下降的過程中,一般不能立即就去減小在線服務的資源,而是要保證其運行一段時間,確認是負載真實的進入平穩狀態,離線才能開始復用在線資源。

首先是對原始數據分桶,分桶后可以消除需要存儲的歷史數據點,減少數據存儲量,如果采用直接存儲歷史點的做法,那么 10w 容器的集群,歷史的點就會成倍線性增加,而采用分桶統計法,則可以將該值變成常量,分桶以后得到一個柱狀圖,利用該柱狀圖進行滑動窗口算法,獲取資源預測的平均值和分位值;然后通過時間衰減函數,將最近的點的權重提升,這樣可以消除該柱狀圖統計出來的歷史比較久遠的數據的作用,進行當前資源的短期預測

另外,分桶的過程中采取的是非均勻分桶,目的是為了實現能夠快速的感知到資源上升,慢速的感應資源下降;我們可以這么簡單的理解,假設所有的點的權重都是一樣的為1(這些權重其實是柱狀圖的高),那么我們采用 P90 作為預測值,其實就是求柱狀圖的面積,如果當前大部分點都是低負載的點,P90 是比較低的值,然后突然有一些點負載突增,他們都會落到范圍較大的桶內,也就是寬度變大,后面的桶面積能夠立馬成為主導面積,那么 P90必定立即會往大桶內移動;

而反過來,當負載從高負載往低負載突降的時候,低負載的點在前面的小桶內,此時小桶的寬度不夠,面積無法成為主導面積,P90 就不會那么快的降低,只有當大部分的點都變低的時候,他們在小桶的高度增加,此時小桶才能成為主導面積,P90 預測值才能下降。

調度增強

在離線混部場景下,由於每個調度器單獨工作,ClusterState 的數據之間沒有進行同步,那么就會發生多個調度器同時選中一個節點,但是資源寫入沖突的問題。

當前的分布式資源調度方案主要是以下幾種類型:

方案(Approach) 資源視圖(Resource choice) 干擾沖突(Interference) 分配粒度(Alloc. granularity) 集群范圍策略
全局調度器(Kubernetes/Borg) 全局視圖 無(串行) 全局搜索,單個調度單元分配 嚴格優先級
靜態分區(比如label分區) 固定子集 無(分區) 分區隔離策略,單個調度單元分配 不同的調度器相互獨立
兩層調度(Mesos/Yarn) 動態子集 悲觀並發 全局搜索,成堆分配,死鎖或者長期等待 嚴格的公平調度
共享狀態(Omega) 全局視圖 樂觀並發 每個調度器可以自己決定如何分配 每個調度器自己的策略

如果讓一個調度器來完成在線和離線業務的調度,往往會導致調度器的邏輯復雜,功能堆積,不便於維護和迭代。特別是在集群規模比較大的時候,調度器在性能、可靠性、迭代速度、靈活性等方面都會受到影響

如果直接部署兩個調度器在集群中,由於多個調度器在同一個 Kubernetes 集群,他們使用同一份集群狀態來完成調度,但是這里對狀態的更新,多個調度器之間是沒有同步的,這會導致調度出現沖突,也就是說兩個調度器會同時選中同一個節點,但是其實當前節點只夠放下其中一個調度器要調度的 Pod,無法同時放置。

共享狀態調度,無論從資源視圖共享性,並發性,資源分配的靈活性以及對多調度器的靈活支持,都表現比較出色。因此 TKE 采用共享狀態樂觀並發的調度方式,該方案對於協調器的性能和可靠性有較高要求,但是它可以做到真實的資源共享,資源視圖的全局一致性,同時還能支持客戶部署多個不同的調度器來針對不同場景進行調度。

TKE 設計和實現了 調度協調器,Kubernetes 調度器只需要在 reserve 階段,開發擴展插件,進行 reserve 的提交,即可完成共享狀態並發。

協調器采用 gRPC 調用,通過消息驅動模式來提升其性能和吞吐量,且協調器目前是非常輕量級設計。

  1. Coordinator 接收到的請求與事件放入后端多維隊列中
  2. 每個 Node 隊列優先處理狀態更新事件以及高優先級的資源請求
  3. 不同 Node 的隊列並發處理
  4. 每個請求只執行最基本的資源沖突檢查,非常輕量

資源保障

TKE 在離線混部,在單機資源保障上,結合 TencentOS 內核,提供了全維度的資源保證;在 Kubernetes 和內核側提供了強有力的資源隔離和保障機制。

多優先級策略

在優先級上,TKE 采用精細化的 CPUSet 編排技術,根據不同類型的服務優先級,比如高優在線業務,將其進行 cpuset 綁核,針對中優在線業務,采用 Cgroup quota 和 cpushare 進行 CPU 資源共享,針對離線業務,則采用離線大框將所有離線業務划分在一個離線 Cgroup 資源池下,但是可以去使用所有的 CPU 核,也可以支持離線業務單獨綁定在和高優在線業務完全互斥的 CPU 子集下。

針對需要綁核的場景,采用超線程避讓綁核分配算法,算法采用貪心策略,優先選取整個 Core 綁定,而不是直接按照邏輯 CPU 進行無差別分配,調度算法可以感知 CPU 拓撲邏輯。

針對內存綁定的場景,采取 Numa 感知的調度策略進行Pod調度。

資源隔離

除了基於傳統 Cgroup 限制與隔離,比如采用 CPU quota、CPU share 進行資源的限制和隔離,采用 cpuset 進行綁核等,TKE 也在內核層次上進行了充分的定制和優化,以適應雲原生場景。

在 CPU 方面,為了在微觀層次應對突發流量以及超線程干擾,TencentOS 雲原生內核支持選取 BT 調度類進行離線任務調度,從而能夠實現在內核級快速減少離線任務干擾,同時能防止離線任務出現飢餓狀態。

BT 調度可以防止多個離線任務出現餓死的現象,當在線服務資源消耗突增,此時為了保證在線服務,往往會壓低離線服務的優先級,離線業務其時間片會越來越少,排在隊首的離線任務,由於一直跑不完,導致其他離線業務全部餓死,騰訊的內核 BT 調度,可以防止多個離線業務之間餓死,交替的執行離線業務。

在內存方面,TencentOS 內核擁有 Cgroup 級別的 cache 清理功能,及時釋放某個容器的 cache, 比如離線業務完成以后,就可以將其 pod 觸發的 page cache 進行及時清理。

在網絡和磁盤 IO 方面,雲原生內核都進行了自研控制,接口都是標准 cgroup 接口,TKE 混部充分利用相關 qos 進行容器的 qos 保證。

干擾檢查

業務的 SLO 干擾檢查,一方面是系統層次的指標的干擾檢查,另一方面是應用層次的指標的干擾檢查

在系統層次,TKE 采集各種系統資源指標,比如感知指令集頻率 CPI,感知系統調用等手段,獲取系統指標干擾。

應用層次,TKE 允許在線業務設置自己的 SLO 干擾閾值,TKE 混部系統能夠回調和檢查業務的 SLO,一旦檢查到業務真實的 SLO 不符合預期,就會采取一系列措施進行干擾源消除,其中包括狀態機控制的信號處理模式,通過壓縮離線資源、禁止離線調度、驅逐等層層遞進的手段,保證業務的 SLO, 以及整個節點的穩定性。

對於離線業務的 SLO,TKE 允許動態優先級調整以及彈性公有雲的方式,避免離線業務長時間等待或者頻繁驅逐,保證離線業務能夠在規定時間內跑完。

總結與展望

本文針對在離線混部中最關鍵的資源保障調度保障,闡述了 TKE 的在離線混部方案,針對資源保障,通過應用優先級划分、內核增強、干擾檢查、超線程避讓等關鍵手段,保證應用間資源隔離;針對調度保障,采用快感知慢回退預測算法、離線大框、共享狀態調度等手段,進行資源彈性復用,解決調度沖突。

未來的混部發展,第一是無差別混部,混部的場景將不再局限於在離線,而是更多復雜類型的負載混部,將會出現更多不同優先等級的負載,進行多優先級資源池的池化處理,資源池間搶占和池間回收技術,充分探索系統層次的資源干擾,如 CPI 干擾檢查,eBPF 觀測技術;第二是混部+彈性的極致結合,混合雲中 IDC 和公有雲極致的資源共享,多雲多集群的資源分時復用調度,以此來達到雲的本質目標--降本增效。

參考

騰訊TencentOS 十年雲原生的迭代演進之路:
https://mp.weixin.qq.com/s/Cbck85WmivAW0mtMYdeEIw

英特爾® 超線程技術:https://www.intel.com/content/www/us/en/architecture-and-technology/hyper-threading/hyper-threading-technology.html

【騰訊雲原生】雲說新品、雲研新術、雲游新活、雲賞資訊,掃碼關注同名公眾號,及時獲取更多干貨!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM