
作者: 舟柒、樓臺
關于熱點機器處理一直是阿里云 Flink 集群運維的一大痛點,不管在日常還是大促都已經是比較嚴重的問題,同時這也是分布式系統的老大難問題。而在今年整個阿里云成本控制的背景下,隨著集群水位的逐步抬升,熱點問題愈發嚴重。日均有上千次的熱點機器出現,并且在晚上業務高峰期,整個熱點持續時間會超過 60min,對于業務以及對于平臺影響是比較大的。
這里的影響是體現在穩定,成本,效率三方面的,首先熱點會導致作業的部分節點延時,高 SLA 要求任務的性能得不到保障,類似于下面這張圖。其次,受熱點機器這個短板的影響,整體集群水位沒有辦法進一步抬升,影響成本控制。最后在我們沒有一個比較好地機制去處理熱點的情況下,是需要人肉并且非常被動地去處理熱點,費時費力,影響效率。
【資料圖】
面對全面影響運維領域(穩定成本效率三個方面)的熱點問題,我們開發的 Flink 集群的自愈系統,出發點就是要解決 Flink 集群的熱點機器問題。
接下來具體分析為什么會產生機器熱點。實際上不管說集群是 20% 還是 60% 的物理水位,整體集群的物理資源對于承載業務來說都是夠用的,K8S 的調度器默認會按照作業的 request 值去盡量平鋪。但是目前阿里云的 Flink 集群是允許任務進行超用的,就會出現下面這個圖的情況。
當任務配置不合理時,會導致部分的 Pod 超用,部分 Pod 不超用。使得機器之間雖然 request 差距不大,但是實際的usage 就會偏差比較大,毛刺的部分節點就會成為熱點機器。上面這幅圖我們可以看到一臺機器上 Pod 的實際消耗在業務高峰期會超過整體的申請值,這個時候就會造成熱點機器。
我們可以得出結論:熱點的出現與水位絕對值多少沒有必然關系,而與作業的超用程度正相關。因此 Flink 熱點的治理都是圍繞著解決作業超用問題展開的。
面對熱點機器問題,可以分為「大促」與「日?!箖深悎鼍啊a槍Υ蟠賵鼍?,任何在大促峰值期間做的運維操作,對于業務來說都是有損的,因此要盡量避免大促期間發生熱點而去執行運維操作,但是我們通??梢酝ㄟ^壓測去合理地預估作業在峰值的行為,通過一些提前的預測的方法在大促前規避作業超用,從而規避熱點的出現。因此,我們設計了一套基于作業的畫像系統,在熱點發生的事前去干預熱點的出現。
針對日常場景,在 7*24 小時保障要求下,熱點發生的頻次高且類型多。疊加用戶操作,平臺變更等非預期行為干擾,往往熱點的出現是相對隨機且沒有辦法提前預測的。我們開發了熱點的事中自愈能力,追求熱點隱患出現后的快速消除,當熱點隱患發生后,能夠在敏感任務受影響的時效內完成熱點壓制。而與之相配套的事后恢復與運維可觀測性能力也同步建設。整體的思路上,仍是圍繞處理超用任務來做,事前畫像是提前規避超用,事中自愈則是對超用的任務進行應急處理。針對熱點發生的時間線,形成了事前畫像,事中自愈,事后恢復,可觀測性四部分的熱點機器解決方案。接下來我會詳細展開介紹這四個部分的能力。
首先什么是事前畫像。前面提到的,事前畫像是針對大促場景下,通過對超用任務的提前規避,來實現消除熱點的方案。要提前規避任務超用,就需要作業在大促峰值的資源配置是精準的。但是目前參與大促的任務,往往作業拓撲是非常復雜的,且作業的數量非常巨大。單純的依靠數據研發同學人肉地去調優每個任務的每個節點是不現實的。因此,事前畫像就是用來解決超大量復雜作業資源精準配置的問題,讓作業在峰值期間不超用運行。
我們設計了一套自動迭代系統,輸入每個任務的目標 RPS,通過全鏈路的壓測平臺與 Flink 任務管控平臺,讓作業經過啟動壓測任務,灌入壓測流量,生成作業畫像結果,停止壓測流量,停止壓測任務,作業利用率及 RPS 實際值比對,更新畫像結果到壓測任務的模擬壓測流程,自動化地執行 N 輪迭代,產出一份作業 usage 與 RPS 均符合預期的資源配置文件。整個迭代過程不需要數據研發同學參與,全自動完成。
除了自動化的迭代流程外,整個環節中最為關鍵的就是畫像是如何產生任務資源配置的,這里的能力是依托于阿里云作業管控平臺中的 Autopilot 服務來完成的。
Autopilot會定時采樣每個 TM 所有資源使用信息(包括 cpu usage, mem usage, delay)等,統計在壓測峰值窗口內TM 使用的資源 p95 值,剔除毛刺或傾斜的 TM 帶來的干擾,并通過 TM 到 ssg 到 task 的映射關系,生成符合大促峰值需求的配置。
在今年的雙 11 大促,事前畫像的能力也得到了了充分的驗證。這 5 個圖中輪次 1 代表畫像迭代前,輪次 2 代表畫像迭代后。
今年大促,實時鏈路團隊緊貼 DT 業務方深入合作,創新性地提出作業畫像結合壓測來智能化地學習、調整作業合理資源配置,不僅在穩定性上實現集群 65% 水位 0 熱點,而且幫助業務降低 17% 成本(如上圖所示),更是幫助 DT 完成上百個作業數千次自動化調優。同時還提出了集群按業務優先級錯峰管理模式,通過 VVP 限流功能與作業動態布局,達成不同優先級作業在各自大促峰值期間滿足延遲要求,提升了集群整體水位,二者在雙 11 生產首次應用,節約了 100 臺機器,在后續大促中也可持續優化應用。
面向超用作業,如何進行事中自愈有多種方案,目前阿里云內部的其他分布式系統主要有以下四種方案 :
a.全局允許超用,也就是以前Flink集群使用的方案b.全局強限制不允許超用;c.通過靜態的規則限制超用;d.動態限制超用能力。
由于實時計算的業務是有其特殊性的(比如說需要有一定的 burst 的能力應對「回追/FO/大促」的場景;低優作業往往傾向于通過犧牲一定程度的性能來換取成本減少;復雜拓撲下不同算子或輕或重的傾斜問題導致資源需求不同等等這些要求)。我們認為超用對于實時任務是一個長期會存在且合理的需求,結合日常,故障,壓測,大促幾種場景比較,第四種方案,也就是通過 Inspector 來實現局部的動態限流是比較合適的方案。在熱點出現時自動化地針對熱點隱患機器上的 作業 進行限流及重調度,讓熱點消除。而在熱點消除后,再根據實際情況重新恢復作業的超用能力。
整體業務流程總的來說分為三個部分,感知,決策,執行。對于事中自愈來說,通過設定閾值與機器學習的方法識別機器異常進行感知,基于SRE 經驗沉淀的決策樹對作業進行決策,通過降級,限流,驅逐等作為執行方法。
在決策這一部分中,以 SRE 的經驗,我們總結了針對熱點處理的決策樹,用來判斷需要選擇什么作業來進行操作。這個決策樹是基于「業務影響」與「熱點快速消除」這兩者的平衡來做。對于平臺側而言,肯定是想要熱點消除的越快越好,也就是直接剔除掉使用最高的作業好了。但是另外一方面,平臺需要承接業務,需要考慮業務方面受不受得了這種操作,也就意味著平臺上的作業會有不同的需求,包括有的作業不接受 FO / 延遲,對他們的作業操作后,我們需要給他們有個解釋等等,這對如何挑選作業增加了難度,需要根據不同的場景在這里進行不同的取舍。我們將業務的重要程度抽象為作業的優先級指標,整個決策樹需要考慮的因子包括作業的優先級,超用程度,規格,黑白名單,以及血緣關系等。
對于具體的決策樹而言,我們首先是考慮業務,追求盡量降低對高優先級業務的影響以及減少對業務的影響面,因此我們優先考慮非白名單的,低優的,超用多的,使用高的作業進行操作。但是由于優先級和超用數值并不是消除熱點的最優路徑,如果一些優先級高的作業使用非常多導致的熱點,也就意味著 Inspector 需要限制很多低優先級的任務才能把熱點降下來,而這意味著,從集群層面來說,對業務的影響面反而增大,并且熱點消除時間相對變長,為了減少影響面以及考慮到可解釋性,我們還增加了從快速消除熱點為出發點的規則,也就是如果優先級高并且超用高于閾值,我們會優先處理這類作業。另外,對于對作業操作的數量來說,我們會設置一個回收的限度,僅回收足夠資源讓機器不熱為止。
上述說的是決策樹方面偏重業務層的考慮,接下來介紹再針對作業驅逐的執行操作上的,且深入到軟件側的技術創新點:
對于「驅逐」操作而言,一般對 Pod 進行驅逐的過程,是將驅逐請求發往 API Server,刪除 Pod 后,由調度器選擇其他節點將 Pod 調度上去。之前黑盒調度指的是在調度器這一環節上,Pod 會受到調度器各種插件的影響,給每個節點進行打分,相對 Inspector 而言,最終 Pod 具體調度到哪一個節點的不確定性比較大,不太明確,這會阻礙 Inspector 后續決策的進一步優化。而我們針對這一點,提出白盒調度,將調度邏輯放入 Inspector 內部,由 Inspector 根據內部算法指定 Pod 所調度到的節點。整個過程會更明確和可控。具體白盒調度實現細節就是 Inspector 會創建 K8S 的 自定義的資源 ReserveResource,在里面指定好這個資源的所屬 owner 就可以了,調度器這邊已經更改好調度的邏輯,適配 Inspector,每次調度 Pod 的時候,會先看 ReserveResource 這個預留的資源的 owner 里面,是否有這個 Pod,如果有,就白盒調度到指定的 Node 上去。不走調度器本身復雜的調度邏輯。
執行的操作方案,除了「驅逐」,還有「限流」,限制整個作業的資源使用量。整個流程為 Inspector 向 JM 發出一個異步的更新請求,發送完請求 Inspector 這邊流程就結束,JM 接收到這個請求之后,先持久化到 TM Pod 創建模板里,保證 新創建的 TM 以及 TM FailOver 了之后,所有 TM 資源限制配置是一樣的,JM 保證了增量的 TM 一致后,再去修改線上存量的 TM 配置,向 API Server 發送 patch 請求修改 TM Pod spec 里的資源配置,TM Pod 所在節點的 kubelet 就會 watch 到這個變化,從而去修改 TM Pod 的 cgroup,借用 Linux 的能力動態限制 TM 的資源使用情況,從而形成「限流」這么一個效果。Inspector 之后會異步地去檢查限流是否生效,與此同時在 K8S Event 中也可以觀察到這個變化。
從執行效果這一角度來看 Inspector 整個事中自愈,熱點的消除的過程,比較 high-level 一點,可以說就是降低低優任務的使用,將資源讓位給高優任務,從而降低它的延遲,這么個效果。對應圖中來講,從 CPU 維度而言,就是通過限制左邊這個低優任務的 CPU 使用,緩解集群熱點情況,讓右邊的高優任務延時降低。
上圖為 Inspector 整體的集群效果,流量高峰期間,產生了 100+ 的熱點,通過開啟 Inspector,將熱點在 3min 內完全壓制。
從單作業角度來看,當熱點機器消除后,很明顯的,處于熱點機器的 TM 延遲就被消除了,數據就會回追回來。
講完事中自愈,對于事后恢復流程來說,剛剛事中自愈中被限流的作業,如果在空閑機器,它有使用需求,那么就需要把限制放開來。通過這種讓作業使用量的峰值錯開,在高優任務使用峰值過去后,低優任務仍能夠使用空閑的機器資源,恢復延時,從而達到兼顧業務穩定性以及提高集群水位的效果。
同樣,面對如何挑選作業的問題,也會有一個制衡,整個過程就和洗手類似,如果水龍頭直接放開到最大,就會水花四濺,對比這里如果直接放開作業的資源使用過猛,單臺機器作業資源使用量突然快速增加,就會將機器迅速打到熱點,從而引發 Inspector 事中自愈,又會將作業資源使用量限制回去,反反復復就會導致如圖中所示的這種「震蕩」的問題,影響集群和作業的穩定性。因此,我們需要通過合理控制作業恢復的頻率與數量,讓作業能夠平緩地追數據,避免震蕩。
作為平臺的 SRE,在服務上線后,需要特別關注服務的「業務效果」與「用戶影響面」,比如看 Inspector 有沒有做出一些有害的操作,出現有害的操作的時候,需要提前想好它的預案,立馬停止不當的操作并且回滾回去。因此需要建立完整的可觀測性能力??傮w來說,可觀測性可以分為兩個角度,一個是偏運維的 SRE 角度,一個是偏使用的用戶角度。對于 SRE 而言,當有熱點機器的時候,我們需要看 Inspector 有沒有做出操作,以及這個操作是否合理,因為正常情況下是沒有熱點機器的,再看看整個決策樹是否可以優化。另外當天的結果復盤時,可以看看 Inspector 的影響面如何,從優先級角度而言,可以看到高優任務受影響比例,形成一個簡單的報表,這些點我們都需要可視化,來幫助 Inspector 的不斷成長從而提高集群的安全水位。對于用戶角度而言,當他們的作業出現「延遲」 或者「FO」的情況時,可以用「可視化的大盤」來查看這些情況是否是 Inspector 操作導致的影響,從而讓用戶自己考慮優化作業,包括調整資源,作業優先級調整等等,讓用戶答疑自閉環,減少工單量。
那么具體實現效果圖而言,可以在 Grafana 上配置大盤,可以看到這段時間 Inspector 操作過的作業數目,以及各個優先級作業匯總情況,以及 誤操作的作業名單,Inspector 操作的詳情,包括熱點機器 sn,作業優先級,熱點機器超用數值等等。這些都可以幫助 Inspector 不斷的優化迭代。
給用戶呈現的大盤里面,用戶可以通過「作業名字」來進行查詢,得到 Inspector 是否有操作過這個作業,以及相應的修改建議等等。
Flink Cluster Inspector 的定位是面向于集群異常的自愈系統,期望通過穩定,成本,效率三大領域的異常進行自愈,實現 Flink 集群的自動駕駛。當前的能力主要集中于成本領域,主要是針對各類熱點機器進行自愈,包括 CPU,內存,磁盤三個維度。后續會往穩定性領域,也就是單節點的異常,系統服務的異常以及集群所承載的業務異常進行自愈,同時會往效率領域拓展,對于整體集群水位以及庫存方面的異常通過彈性的擴縮容能力進行自愈。
目前整個系統都是圍繞云原生構建的,在 Flink 系統云原生化的背景下,運維能力也全面云原生化,基于云原生的技術棧如 Operator,SideCar,申明式 API 等,構建了圍繞 CR 開發,基于 GitOps 的 CI/CD,以及可觀測高可用的運維。而承載上述業務能力的技術內核,則是緊貼于調度系統的異常自愈框架,我們抽象了針對異常自愈的感知,決策,執行三個關鍵環節,并通過一個統一的框架整合,方便各運維同學以插件式的方式快速實現各自的業務需求。同時也深度貼合調度層,與 K8S 的同學協同,開發面向于 Flink 場景的調度器增強能力。
基于以上 Inspector 的能力,我們將 Flink 集群打造成為一個將成本穩定性效率串聯起來的聯動系統,進行精細化的成本控制。我們定義了 24h 平均安全水位和瞬時安全水位,分別用來衡量集群的成本控制能力,和集群穩定性問題臨界能力。通過設置當前所能達到的安全水位,當集群水位較低的時候,能夠通過隔離業務,在業務影響面最低的情況下將機器下線。而如果集群水位過高,則快速申請預算,進行機器的擴容。通過 Inspector 中動態容量維持模塊,將集群水位始終控制在安全水位附近。
在某些緊急情況下,集群的瞬時值可能會過高,觸發集群整體穩定性問題。當水位已經超過了所能夠承載的安全水位上限,則需要進入應急處理流程,通過 3-5-20 報警處理,批作業限制,大促緊急預案等消除異常。當水位仍在安全水位范圍內,由自愈服務進行兜底,通過自動化的將異常的機器或者業務進行隔離或限制,將穩定性問題自動恢復。容量模塊不斷抬升水位,錘煉自愈服務的可靠性,而自愈能力的增強,又能夠反過來提升安全水位,進而抬升集群水位,形成聯動。
標簽: 可觀測性