深入理解YARN 公平調度器的搶佔

http://blog.cloudera.com/blog/2018/06/yarn-fairscheduler-preemption-deep-dive/

揭秘Apache Hadoop YARN 系列博客中介紹了YARN 調度如何工作。

本文中我們討論公平調度(FairScheduler)搶佔執行的技術細節, 和配置公平調度搶佔的最佳時間。

還會介紹CDH 5.11中公平調度搶佔近期的一些調整,CDH 5.11嘗試解決很多問題,這些問題都列在YARN-4752中。

https://issues.apache.org/jira/browse/YARN-4752?subTaskView=all

深入理解YARN 公平調度器的搶佔

定義(Definitions)

開始之前,有必要解釋一下公平調度隊列的一些關鍵屬性。

FairShare 是公平調度器的概念,表示資源的度量值,格式一般為<memory>

Steady FairShare(理論FairShare)

公平調度使用分層的隊列。父級一樣的隊列是兄弟隊列。隊列的weight決定了一個隊列相對於其兄弟隊列應該分得多少資源。 這些資源的值就是Steady FairShare。Steady FairShare 在隊列的層級計算,root 隊列的值就是集群的所有資源。Steady FairShare 的計算公式為:

深入理解YARN 公平調度器的搶佔

計算的數值只是隊列資源的期待值,開啟搶佔時,並不是調度的最終決定。換句話說,這只是隊列的理論FairShare。

舉個例子,假定YARN共有12 核心和24GB 內存。需要配置3個隊列,那麼Steady FairShare 值根據weight計算如下:

深入理解YARN 公平調度器的搶佔

Instantaneous FairShare(即時FairShare)

為了滿足多租戶集群的靈活性。 公平調度器允許隊列在集群有空閒資源時使用比 Steady FairShare 更多的資源。

活躍隊列( active queue)是指至少正在運行一個應用的隊列,非活躍隊列就是沒有正在運行應用的隊列。

Instantaneous FairShare 是活躍隊列計算後FairShare。它並不是指隊列的預留資源值。要使Instantaneous FairShare 生效, 必須要配置搶佔(preemption)可用和下面討論的FairShare Starvation。

深入理解YARN 公平調度器的搶佔

和Steady FairShare的不同之處是非活躍隊列不分配Instantaneous FairShare。當所有隊列都處於活躍狀態時,兩個值是一樣的。

在上面的例子中,如果只有tenant1和tenant2是活躍的,那麼Instantaneous FairShare 的計算如下:

深入理解YARN 公平調度器的搶佔

注意 FairShare 通常用來模糊的指代 兩種 FairShare 中的一個。 理解不同場景下指代的是哪一種FairShare是很重要的。本文中,除非明確指出,否則FairShare指的是Instantaneous FairShare。

最小Share(Minimum Share)

隊列可以指定需求資源的最小值。也指代隊列的MinShare 。MinShare 並不是隊列保留的最小資源。MinShare 只有在下麵條件都為真時生效:

  • 隊列時活躍的
  • 搶佔時可用的
  • MinShare Starvation(下面章節討論) 已配置

飢餓和搶佔(Starvation and Preemption)

Starvation 和 Preemption 是相關的,最好放在一起討論。

由於公平調度器的彈性特點,隊列在運行應用時,可以使其它應用(運行在相同或則不同隊列中的應用)保持飢餓(starved)狀態。在上面的例子中,假如只有tenant1和tenant2 隊列是活躍的,並且分別持有33.3%和66.6%的資源。

隨後,如果tenant3變成活躍狀態。各個租戶的Instantaneous FairShare會變成25%, 50% 和 25%。tenant3中的應用必須等待tenant1 和 tenant2中的應用結束使用資源。在那之前,tenant3一直會有為滿足需求或者飢餓的待定容器 。

搶佔允許通過一種可預見的方式糾正這種不平衡。它可以從隊列回收超過他們FairShare的資源,而不必等他們釋放資源。

使搶佔有效

YARN 公平調度器會搶佔那些超過自己的 Instantaneous FairShare 值的隊列中正在運行的容器, 搶佔條件要滿足:

  1. 有一個或者多個飢餓狀態的應用。
  2. 搶佔有效

當下麵條件滿足時,搶佔有效

  1. 通過配置yarn.scheduler.fair.preemption 使YARN 服務的搶佔有效
  2. 集群層次的資源使用超過yarn.scheduler.fair.preemption.cluster-utilization-threshold 的配置,默認使80%

集群使用率是搶佔經常被忽略的一個前提條件。當一個集群使用率很低而又發生了搶佔容器,引發不必要的容器交換,影響性能。集群級別資源使用率是基於核心和內存使用百分比計算的,取他們較大的一個。

有需要時,隊列可以被標記為不可被搶佔。例如一個高優先級別隊列的資源是不可被搶佔的。配置隊列不可搶佔,可以參考文檔。https://www.cloudera.com/documentation/enterprise/latest/topics/admin_preemption.html

深入理解YARN 公平調度器的搶佔

兩種類型的飢餓狀態(starvation)

1. FairShare Starvation

2. MinShare Starvation

FairShare Starvation

滿足下列條件時,應用是FairShare Starvation

  1. 應用需求的資源沒有滿足
  2. 應用使用的資源少於他的Instantaneous FairShare.
  3. 應用使用的資源在他Instantaneous FairShare 的FairShare 搶佔限制(FairShare Preemption Threshold)以下的狀態,至少保持了FairShare 搶佔超時時間(FairShare Preemption Timeout)。

FairShare Preemption Threshold 默認是0.5。FairShare Preemption Timeout 默認不設置,為了是應用飢餓,需要明確設置。這兩個參數都可以全局設置和按隊列設置。

例如,假定有一個隊列,FairShare Preemption Timeout是5秒,FairShare Preemption Threshold是0.8。這就暗示了,如果搶佔有效和條件1,2滿足,當應用在5秒內沒有得到相當於隊列Instantaneous FairShare值的80%的資源,公平調度器會任務應用是飢餓的。

需要注意的是:搶佔有效並不保證應用或者隊列會獲取全部的Instantaneous FairShare。只能保證應用或者隊列在獲取到足夠資源時,不再被認為是飢餓的。這就意味著只會在超時時間(FairShare Preemption Timeout )之後,隊列資源才會提升到對列的Instantaneous FairShare 值的 FairShare 搶佔上限那麼多。除了需要使搶佔有效,還需要Resource Manager 能找到可以被搶佔的容器。

對於一個高優先級的隊列,通過設置FairShare Preemption Threshold 高比例, 設置FairShare Preemption Timeout 為比較小的時間間隔,並且設置為不可搶佔,來使隊列很容易飢餓。查看這篇博客(https://blog.cloudera.com/blog/2017/02/untangling-apache-hadoop-yarn-part-5-using-fairscheduler-queue-properties/)

的幾個例子,可以瞭解到怎麼通過設置搶佔屬性來控制應用優先級。

在一個隊列中嚮應用分配FairShare。

運行在一個隊列中應用總是平均的分配隊列的Instantaneous FairShare。FairShare是按隊列配置的,對於實現應用級別的FairShare 分配, FairShare starvation 是很關鍵的。

之所以重要是因為,即使對列不是飢餓狀態,隊列中的一個或者多個應用也可以是飢餓的。一個應用超過了他的 Instantaneous FairShare, 在任何隊列中的飢餓狀態的應用都可以搶佔他的容器。同一個隊列中的應用也可以。

MinShare(最小資源) Starvation

滿足以下條件時,隊列是MinShare Starvation 的:

  1. 隊列中一個或者多個應用資源未滿足需求
  2. 隊列的資源使用少於他的MinShare
  3. 隊列的資源使用保持在MinShare以下至少MinShare Preemption Timeout 這麼久

MinShare Preemption Timeout 默認不設置,為了讓對列飢餓,需要明確設置。這個參數可以全局設置,也可按隊列設置。

隊列中嚮應用分配最小資源

MinShare可以指定到隊列粒度,和FairShare不同的是,應用不能MinShare(最小資源) Starvation。

在分配最小資源時,處於同一MinShare(最小資源) Starvation的隊列中應用按資源需求量排序。這可能導致即使隊列的最小資源分配完了,隊列中一些應用仍然處於飢餓狀態。

比如, 假定隊列的最小內存設置,對列只有6G內存,比最小內存小。這個隊列中有App1, App2, App3 和App4 4個應用,分別需求內存3G, 2G, 1G, 和0.5G。 App1會得到3G,App2會得到2G, App3 會得到1G, App4因為內存已經分配完而得不到內存。

搶佔的容器

應用的資源請求可能會通過搶佔一個或多個節點上的容器來達成。當有多個節點上的容器滿足需求時,擁有最少Application Master 容器的節點會優先被搶佔。另外,當下面2點滿足時,容器才會被搶佔。

  • 容器中應用的隊列時可搶佔的
  • kill掉容器不會讓應用資源調到FairShare之下。換句話說,如果應用在被搶佔之後資源少於他的FairShare,那麼他是不會被搶佔。

MinShare 不是在決定哪個容器搶佔的時候用。MinShare只用在配置Starvation。這一點很重要值得重複說明。即便,FairShare或者MinShare 配置了,也只有在應用超過FairShare的時候才會被搶佔,如下:

深入理解YARN 公平調度器的搶佔

配置飢餓(Starvation)的最佳實踐

推薦配置FairShare starvation 。不推薦配置 MinShare starvation 或者最小資源, 因為增加了調試搶佔問題的複雜度,而沒有明顯的好處:

  • 當最小資源飢餓發生時,容器所在隊列超過MinShare 而沒有超過FairShare捕獲被搶佔。
  • 最小飢餓狀態的資源,不是均勻的分配給隊列中的應用,而時按需求量來分。不同於FairShare 飢餓狀態的分配方式。
  • 如果隊列的最小資源值大於他的FairShare值,最小資源值就會變成隊列的FairShare。會降低其它隊列的Fair'Share。

隊列的權重對於核心和內存是相同百分比的。有些隊列會針對核心和內存進行不同配置。這時有理由配置MinShare Starvation。儘管如此,也必須確保所有隊列的最小資源總和不大於總資源。否則,飢餓和搶佔行為會變得不可預測。例如,一些隊列會總是MinShare 飢餓,但是不會去搶佔容器,因為其它應用的資源可能一直小於他們的FairShare。

搶佔的大修改

最近的代碼改動包括了一些改進和bug修復。 CDH 5.11.0 及以後的版本,下列改進可用:

  • 搶佔之後的資源滿足飢餓應用的需求時,才會發生搶佔。確保搶佔的資源不會不被使用。
  • 除非沒有其它的容器搶佔,否則不會搶佔Application Master的容器。

搶佔相關配置大都沒有改變,除了yarn.scheduler.fair.preemptionInterval 變得不可用。

挑選搶佔容器的方式也有改變。以前,超過FairShare 最多的容器會優先搶佔。這次改動後,會從所有超出FairShare的應用搶佔。

已知的問題

當應用飢餓,會從兄弟應用或者其它對列中的應用搶佔資源。然而,不保證飢餓應用會收到搶佔的容器。

有可能,另外一個飢餓應用會受到那些容器資源。這個問題在YARN-6432 和YARN-6895 被Fixed, 在CDH6.0以後可用。

搶佔調優的工具

檢測FairShare 和隊列指標

在Cloudera Manager中, 可使用YARN服務中資源池tab ,觀察Steady 和 Instantaneous FairShare,以及實際資源分配。

深入理解YARN 公平調度器的搶佔

Cloudera Manager 同時可以監控對列的其它指標。

  • 在CM 報告頁面,點擊Clusters > ClusterName > Reports > Historical Applications By YARN Pool.
  • 使用tsquery 檢索和繪製YARN pool 指標

當前應用,隊列和FairShare 也能通過Resource Manager的調度部分檢測。注意如展示的一樣,只展示內存使用,不展示核心使用。

深入理解YARN 公平調度器的搶佔


分享到:


相關文章: