第4章:YARN

Apache YARN(Yet Another Resource Negotiator)是一個Hadoop集羣資源管理系統。YARN是在Hadoop 2引入的,用以改善MapReduce的表現。可是它也足夠勝任其它的分佈式計算框架。java

YARN提供了一些能被請求調用的APIs,並處理集羣資源。可是一般用戶不會直接調用這些APIs,而是調用由分佈計算框架提供的更高級別的APIs。這些更高級別的APIs基於YARN創建,並對用戶隱藏了資源管理的細節。圖4-1說明了這個情景,並顯示了一些分佈式計算框架(MapReduce,Spark等等)做爲YARN應用位於集羣計算層(YARN)和存儲層之上(HDFS和Hbase)。
圖4-1:YARN應用
圖4-1框架表示的應用層之上還有一層應用,如Pig,Hive和Crunch。它們都運行在MapReduce,Spark或Tez(或同時三者)之上,並不和YARN直接交互。node

這一章節帶領你們過一遍YARN的特性,爲理解第四部分章節的內容(包括一些分佈式處理框架)打下基礎。算法

YARN應用運行分析

YARN經過兩種一直運行的守護進程來提供它的核心服務。一種是資源管理器(一個集羣一個),管理集羣中全部資源的使用,另外一種是節點管理器,在全部節點上運行,啓動或監控容器。容器會使用分配的有限資源的集合(內存,CPU等)執行應用特定的進程。取決於YARN是如何配置的,容器能夠是一個Unix進程,也能夠是一個Linux cgroup(control groups)。圖4-2顯示了YARN怎麼樣運行應用的。
圖4-2:YARN怎麼樣運行應用shell

爲了運行基於YARN的應用,客戶端必須與資源管理器(resource manager)通訊,請求它運行一個應用主進程(圖4-2步驟1)。資源管理器而後尋找可以在容器中啓動這個應用主進程的節點管理器(步驟2a和2b)。應用啓動後,具體可以作什麼取決於應用自己。它能夠在它所在的容器中簡單地執行一個計算而後將結果返回給客戶端。或者它能夠向資源管理器請求更多的容器(步驟3),以便運行分佈式計算(步驟4a和4b)。後者是MapReduce YARN應用所作的事,咱們將會在"一個MapRedue做業運行分析"小節中詳細地學習。apache

從圖4-2咱們注意到,YARN自己不提供任何方法讓應用各部分(客戶端,主進程,進程)間進行通訊。大多數特殊的YARN應用使用遠程調用的形式(例如Hadoop的RPC),將更新的狀態和結果傳遞迴客戶端,可是這不是正常狀況。編程

資源請求

YARN對於資源請求的形式要求比較靈活。某個請求,請求多個容器,能夠對每個容器都指定須要的計算機硬件資源(內存,CPU等),並可以指定位置限定的一些容器。緩存

位置對於一些分佈式的數據處理算法可以充分高效地使用集羣帶寬是很重要的。因此YARN容許應用指定它請求的容器的位置。位置限定能夠指定位於某個特定的節點或機架,或者集羣中任意位置(好比:不在機架上的)的容器。服務器

有時,並不可以知足位置限定的條件,這種狀況下,要未不分配任何位置,要未,選擇放寬限定條件。例如,指定了某個節點,可是不可能在這個節點上啓動容器(由於其它容器正在它上面運行),那麼YARN將會嘗試啓動位於相同機架上的其它節點上的容器,或者其它節點也不可用時,就啓動集羣中任意一個節點上的容器。併發

啓動一個容器處理HDFS塊(比方說,執行MapReduce中的一個map任務),一般狀況下,應用會請求保存了塊三個複本的那個節點,或者保存了這些複本的機架中的某個節點,若是以上都失敗了,就選擇集羣中任意一個節點上的容器。框架

一個YARN容器能夠在它運行時的任意時間發起資源請求。例如,一個應用能夠預先發起所需全部資源的請求,也能夠以一種更加動態的途徑,即當應用有更改時,再動態地請求更多資源。

Spark採起了第一種途徑,在集羣中啓動固定數量的執行器(「參看在YARN上的Spark 」章節)。另外一方面,MapReduce會採起這兩種途徑。執行map任務時會預先請求全部容器,執行reduce任務的容器不會當即啓動,會在後面啓動。並且,若是有任何任務處理失敗了,將會請求額外的容器從新執行失敗的任務。

應用的生命週期

一個YARN應用的生命週期能夠千差萬別,從幾秒的短命應用到能夠運行數天甚至數月的長期應用。可行的應用歸類是根據應用與做業之間的映射關係而不是應用運行的時間來進行分類。最簡單的狀況是每個做業對應一個應用,MapReduce任務採起的就是這個途徑。

第二個模式是每個工做流運行一個應用或多個做業(多是不相關的做業)運行一個應用。這種途徑比第一個途徑更高效,由於應用容器能夠被多個做業共用,也能夠緩存多個做業產生的中間數據。Spark就是一個使用這種模式的例子。

第三個模式是被不一樣用戶共享的長生命週期應用。這種應用常常是以某種配合的角色發揮做用。例如Apache Slider就有一個長期運行的應用管理器,這個應用管理器做用是啓動集羣中的其它應用。Impala經過這個途徑來提供一個代理應用,用於響應Impala實體機的資源請求。經過使用這種"一直運行"的應用管理器,用戶能夠得到低延遲響應,由於當用戶查詢時不須要啓動一個新的應用管理器了。

構建YARN應用

從頭開始寫一個YARN應用是至關複雜地,可是大多數狀況沒必要要。由於可使用一個已經存在的應用,進行調整以適應本身地需求。例如,若是你對有向無環圖(DAG)感興趣,那麼Spark或者Tez是合適的,或者對流式處理感興趣,Spark,Samza或者Storm是合適的。

有不少工程用於簡化構建一個YARN應用時的操做。早先提到的Apache Slider讓現有的分佈式應用運行在YARN上成爲可能。用戶能夠在集羣上運行他們本身的應用(例如HBase)而不影響其它用戶,不一樣的用戶能夠運行同一個應用不一樣的版本。Slider可以改變應用運行的節點數量,掛起和恢復運行某個應用。

Apache Twill與Slider類似,但除了以上功能,另外還能夠提供一個簡單的編程模型,能夠開發基於YARN的分佈式應用。Twill容許你定義實現了Java Runnable接口的集羣進程,而後在集羣的YARN容器中運行它們。Twill還提供實時日誌(記錄可執行進程的事件以流形式返回客戶端)和命令消息(將客戶端的命令發送給可執行進程)。

當以上選擇都不能知足要求時,例如須要開發一個可以進行復雜時間調度的YARN應用。那麼YARN工程中有一個分佈式的shell應用能夠作爲如何開發YARN應用的例子,它演示瞭如何使用YARN APIs在客戶端、應用管理器與YARN守護進程之間交互通訊。

YARN與MapReduce 1比較

在Hadoop最第一版本(版本1或更早)中的MapReduce有時被稱爲"MapReduce 1",以和MapReduce 2區分開。MapReduce 2是Hadoop 2或以後的版本,它使用了YARN。

有一件重要的事情,那就是舊的和新的MapReduce APIs與MapReduce1和MapReduce2並非一回事。APIs是面向用戶,客戶端的,決定了你如何寫MapReduce程序(參看附錄D),然而MapReduce1和2僅僅是運行MapReduce程序不一樣的方法。舊的和新的MapReduce APIs均可以在MapReduce1和2中運行。

在MapReduce1中,有兩種控制做業執行過程的守護進程,一種是jobtracker,一種是一個或多個tasktracker。jobtracker組合系統中須要運行的全部做業,而後分配運行在tasktracker上的任務。Tasktracker執行任務,並將進度報告發送給jobtracker,jobtracker將會保存每個做業的整個進度。若是一個任務失敗了,jobtracker將會在另外一個tasktracker上啓動它。

在MapReduce1中,jobtracker既關心做業的調度(匹配tasktracker與task),又關心任務的進度(跟蹤任務,重啓失敗的任務,顯示任務,記錄任務,例如維護任務數)。相對地,在YARN中,這些責任由不一樣的實體處理:資源管理器和應用管理器(一個MapReduce做業一個應用管理器)。jobtracker還須要存儲已經完成的做業的歷史記錄。固然也能夠單獨運行一個歷史記錄服務來給jobtracker減負。在YARN中,具備相同角色的是時間線服務,它存儲應用的歷史記錄。

在YARN應用中,與tasktracker等效的是節點管理器。MapReduce1與YARN的功能映射關係如表4-1所示:

MapReduce 1 YARN
Jobtracker 資源管理器,應用管理器,時間線服務
Tasktracker 節點管理器
槽(Slot) 容器

設計YARN的目的是解決MapReduce 1的一些侷限性。使用YARN有以下好處:

  • 擴展性
    YARN能夠運行在比MapReduce 1更大的集羣上。當達到4000節點或4000個任務時,MapReduce 1就達到了瓶頸。由於jobtracker必需要管理做業和任務。YARN經過使用分開的資源管理與應用管理的結構克服了這個限制,YARN設計的目的是能擴展到10000個節點和100000個任務。
  • 高可用性
    HA(High availability 高可用)是當正在服務的實體機故障時,經過複製所需的狀態和數據到另一臺實體機上,執行所需的工做,繼續提供服務來實現的。然而jobtracker內存中大量快速地改變複雜的狀態(例如,每幾秒鐘每個task狀態就會更新一次)使HA應用到jobtracker變得很是困難。
    YARN經過將jobtracker的功能分解到資源管理器和應用管理器,使服務高度可用變成了一個能夠分開克服的問題。那就是爲資源管理器提供HA,而後爲YARN應用(以每個應用爲基礎單位)提供HA。實際小,Hadoop 2支持MapReduce做業中的資源 管理器和應用管理器HA。YARN中的故障恢復將在第7章"故障"小節中詳細講解。
  • 實用性
    在MapReduce 1中,每一個tasktracker經過一個位置固定,大小固定的"槽"中配置,槽分爲map槽和reduce槽。map槽只能用於運行map任務,相應的,reduce槽只能用於reduce任務。
    在YARN中,一個節點管理器管理一個資源池,而不是數量固定的指定的槽。YARN上的運行的MapReduce不會出現因爲集羣中僅僅有map槽,reduce任務必須等待的狀況。這種狀況可能發生在MapReduce 1中.YARN中,若是運行任務時,資源可得,那麼應用就應該可以使用它們。
    並且,YARN中的資源是精細化管理的,因此應用能夠請求它所須要的資源,而沒必要請求一個槽。對於某些特殊的任務來講,槽太大的話,會形成資源浪費,過小的話,形成任務失敗。
  • 多用性
    從某些方面來講,YARN最大的優點是它使Hadoop可以使用除了MapReduce其它類型的分佈式應用。MapReduce僅僅是其中一個YARN應用。

    用戶甚至可以在同一個集羣中運行不一樣版本的MapReduce應用。這就使得升級MapReduce變得更加容易管理。(注意,MapReduce中的某些部分,例如做業歷史記錄服務器,shuffle處理器和YARN自己仍然須要整個集羣一塊兒升級。)

既然Hadoop 2被普遍使用,並且是最新的穩定版本。這本書中剩餘部份內容中"MapReduce"指的就是"MapReduce 2"。第7章將會詳細地講解MapReduce如何運行在YARN之上。

YARN中的調度計劃

理想狀況下,一個YARN應用的請求應該馬上響應。然而,現實狀況是,資源是有限的,並且集羣繁忙時,應用常常須要等待直到它的部分請求獲得知足。YARN調度器的工做就是根據一些既定的規則給應用分配資源。調度一般是一個困難的問題,沒有一個最好的規則。這也就是爲何YARN提供調度器和可配置規則兩種選擇的緣由。咱們接下來詳細看看。

調度器

YARN中有三種調度器:FIFO調度器,容量調度器和公平調度器。FIFO調度器將應用放在一個隊列中,按照它們提交的順序運行它們(先進,先出)。隊列中第一個應用的請求首先知足。一旦它的請求被知足了以後,就服務隊列中下一個應用,依次類推。

FIFO的優勢是容易理解,並且不須要配置。可是它不適合資源共享的集羣。通常大的應用會用到集羣中全部資源,若是使用FIFO,每個應用必需要按序等待。在資源共享的集羣中,最好使用容量調度器或者公平調度器。兩者都會使那些運行時間長的做業可以在合理時間內完成,並且也使得用戶在執行少許的臨時的併發查詢時,可以在合理的時間內返回結果。

調度器之間的區別如圖4-3所示,咱們能夠看到,FIFO調度模式(i)下,小的做業必需要等待大的做業完成以後才能執行。

在容量調度模式(ii)下,一個分開的專用的隊列容許小的做業一提交就可以執行。這是以整個集羣的可利用空間爲代價的,由於須要爲這個專用隊列預留空間。這也意味着大的做業比使用FIFO調度完成的晚。

在公平調度模式(iii)下,不須要預留必定數量的空間。由於它會動態的平衡全部運行的做業所需的空間資源。第一個(大)做業啓動後(目前是集羣中惟一運行的做業),它會獲取集羣中全部的資源,當第二個(小)做業啓動後,它將把一半資源分配給第二個做業。這樣,每個做業都能分到相同數量的資源。

注意到,第二個做業啓動到它接收到所分的資源有必定的延遲。由於必須等待資源從第一個做業使用的容器中釋放出來後才能使用。在小做業完成,並再也不請求資源後,大的做業又將使用集羣中全部的資源。這個模式形成集羣的高佔用空間和小做業及時的完成。

圖4-3對比了這三個調試器基本操做。接下來的兩部分,咱們將學習容量和公平調度器中一些高級的配置。

圖4-3:分別在FIFO(i),容量(ii),公平調度(iii)模式下運行一個大做業和一個小做業的集羣空間使用量

容量調度器配置

容量調度器容許按照組織的行形式共享Hadoop集羣資源,每個組織都分配了總集羣資源中的一部分資源。每個組織都設一個專用的隊列。能夠配置隊列使用集羣中指定的部分資源。隊列也許能夠進一步按層級劃分,使得每個組織能夠將它的資源分配給不一樣組的用戶。在隊列中,應用按照FIFO規則進行調度。

正如咱們在圖4-3看到的那樣,單個做業不能使用超過它所在隊列容量的資源。然而,若是隊列中的做業超過一個,而且有空閒的資源,那麼容量調度器也許會將剩餘的資源分配給這個隊列中的做業,即便會超出隊列的容量(應分配的資源)1,這就是所熟知的"彈性隊列"。

正常操做時,容量調度器不會強制地殺死做業來回收容器2,因此若是一個隊列因爲缺乏請求而容量不夠,而後增長請求,若是其它隊列中做業完成,有資源從容器中釋放出來,隊列將會佔用其它隊列的資源。經過配置隊列的最大容量能夠限制隊列不佔用其它隊列太多資源。但這是以隊列的彈性爲代價,固然,經過不斷嘗試與錯誤,應該能找到一個合理的平衡點。

假設隊列層級以下面這樣:

示例4-1顯示了一個容量調度器配置文件,這個配置文件叫作capacity-scheduler.xml。對應於上面的層級,在root隊列下定義了兩個隊列,prod,dev,分別佔40%和60%的資源。注意,能夠經過屬性yarn.scheduler.capacity. . 來配置隊列特殊的屬性。 是隊列的層級路徑(以點分隔),例如root.prod。

示例:4-1:容量調度器的基本配置文件
<?xml version="1.0"?>
<configuration>
  <property>
    <name>yarn.scheduler.capacity.root.queues</name>
    <value>prod,dev</value>
 </property>
 <property>
   <name>yarn.scheduler.capacity.root.dev.queues</name>
   <value>eng,science</value>
</property>
<property>
    <name>yarn.scheduler.capacity.root.prod.capacity</name>
    <value>40</value>
</property>
<property>
    <name>yarn.scheduler.capacity.root.dev.capacity</name>
    <value>60</value> 
 </property>
 <property>
    <name>yarn.scheduler.capacity.root.dev.maximum-capacity</name>
    <value>75</value>
 </property>
 <property>
     <name>yarn.scheduler.capacity.root.dev.eng.capacity</name>
     <value>50</value>
 </property>
 <property>
   <name>yarn.scheduler.capacity.root.dev.science.capacity</name>
    <value>50</value>
 </property>
</configuration>

正如你看到的那樣,dev隊列進一步分紅了相同大小的eng和science隊列。因此當prod隊列空閒的時候,dev隊列沒有使用集羣全部的資源,它最大的使用資源設置爲75%。換句話說,prod隊列老是有25%資源能夠當即使用。由於其它隊列沒有設置最大資源,eng或者science隊列中的做業可使用dev隊列全部的資源(最多佔集羣的75%),或者對於prod隊列來講,實際可以使用集羣全部資源。

除了配置隊列的層級以及容量,還能夠控制一個用戶或應用能夠分配的資源最大數量,同時能夠運行的應用數,隊列的ACLs控制(權限控制)。詳細說明請參考Hadoop: Capacity Scheduler

隊列指定
指定應用放在哪一個隊列是在應用端進行指定的。例如,在MapReduce
中,你將屬性mapreduce.job.queue.name的值設置爲你想存放的隊列的名字。若是指定的隊列名不存在,將會在提交做業時報出錯誤。若是沒有指定隊列,則應用會放在叫作default的隊列中。

對於容量調度器而言,隊列名稱是層級結構最後一級的名字,全路徑名稱將不識別。因此,拿先前的配置例子來說,prod和eng這樣寫沒問題,但root.dev.eng和dev.eng就不行。

公平調度器的配置

公平調度器試着使全部正運行的應用獲得相同的資源。圖4-3顯示了在同一個隊列中應用是怎麼樣平均分配資源的。然而,對於多個隊列,仍然能夠平均分配,下面將加以說明。

在公平調度器上下文中,隊列和池能夠互換使用,意思是同樣的

爲了理解資源是如何在隊列間平分的,假設有兩個用戶A和B,每個用戶都有本身的隊列(圖4-4)。A用戶啓動了一個做業,因爲B沒有請求資源,這個做業將獲得集羣全部的資源。而後,B也啓動了一個做業,A的做業仍然在運行,一會以後,每個做業都能獲得一半的資源,就像咱們先前看到的那樣。如今,若是B啓動了第二個做業,這時其它做業仍在運行。B將把它的資源分配給他啓動的其它做業,這樣,B的每個做業都將佔有四分之一的資源。A仍然佔有二分之一的資源。這樣資源在用戶之間平均分配了。圖4-4:用戶隊列間的資源分配

啓用公平調度器
使用哪一個調度器是經過yarn.resourcemanager.scheduler.class屬性決定的。默認是容量調度器(在有些hadoop分佈式系統,例如CDH中,默認是使用公平調度器)。經過在yarn-site.xml配置文件中配置yarn.resourcemanager.scheduler.class來改變默認的調度器,它的值是調度器的全路徑類名:org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler。

隊列配置
公平調度器在一個叫作fair-scheduler.xml的配置文件中配置,這個配置文件在加載classpath指定的類時一同被加載,配置文件的名字能夠經過屬性yarn.scheduler.fair.allocation.file設置。每個應用被放在以用戶名命名的隊列中,當用戶提交第一個應用時,隊列就會被動態地建立。

在配置文件中,配置每個隊列,能夠像容量調度器同樣按照層級進行配置。例如,咱們能夠按照咱們在容量調度器中定義的那樣定義prod和dev隊列,如示例4-2。

示例4-2:公平調度器的配置文件
<?xml version="1.0"?>
<allocations>
   <defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>
<queue name="prod">
  <weight>40</weight>
  <schedulingPolicy>fifo</schedulingPolicy>
</queue>
<queue name="dev">
   <weight>60</weight>
   <queue name="eng" />
   <queue name="science" />
</queue>
<queuePlacementPolicy>
   <rule name="specified" create="false" />
   <rule name="primaryGroup" create="false" />
    <rule name="default" queue="dev.eng" />
</queuePlacementPolicy>
</allocations>

隊列的層級定義經過使用嵌套的queue節點。全部的隊列是root隊列的子隊列,即便實現上沒有嵌套在root隊列節點下。這裏,咱們又將dev隊列分紅eng和science兩個子隊列。

隊列能夠有重量,用於公平分享資源時的計算。在這個例子中,集羣將prod和dev隊列按照40:60的比例分配資源,這樣分配是公平的。eng和science沒有指定重量,因此它們是平均分配的。重量和比例不徹底同樣,這個示例中,咱們使用加起來等於100的重量只是爲了簡便起見。咱們也能給prod和dev隊列的重量都指定2或3.

當設置重量的時候,記得考慮到"默認隊列"和動態生成的隊列(例如那些以客戶命名的隊列)。沒有在配置文件中指定的隊列,重量都是1。

這些隊列能夠有不一樣的調度規則。默認的規則能夠經過頂級節點defaultQueueSchedulingPolicy設置。若是省略了這個節點,將使用公平調度規則。不能只看它的名字是「公平」,公平調度器也支持FIFO(fifo)規則和後面將講到的優點資源公平規則(drf Dominant Resource Fairness)。

某個特定隊列的調度規則能夠經過它的schedulingPolicy屬性覆蓋。如上面的配置文件,prod隊列使用FIFO調度規則,由於咱們想要每個做業按順序執行而且能在最短的時間內執行完。注意一點的是,prod和dev隊列仍然使用公平調度規則進行資源的劃分,eng和science隊列也是同樣。

雖然沒有在以上配置文件中顯示出來,但還能夠配置隊列能使用的最小或最大資源空間,和隊列中最多運行的應用數(詳細配置參看此頁)。最小資源空間不是一個硬性限制,而是調度器用來優先分配資源的。例如若是兩個隊列的資源都不夠,那麼離最小資源分配要求差距最大的將優先分配到資源。最小資源的設置還可用於優先佔有,稍後將討論到。

隊列指定
公平調度器使用必定的規則來決定應用放在哪一個隊列中。如示例4-2,queuePlacementPolicy節點包含一系列規則,系統將按順序嘗試每一條規則,直到匹配到一條。第一條規則,specified指定應用放在哪個隊列中,若是沒有指定或指定的隊列不存在,這條規則不符合,將嘗試下一條規則。primaryGroup規則指定應用放在與用戶的主Unix組名相同的隊列中。若是不存在這樣的隊列,則嘗試下一條規則。default規則是上面的規則都不知足時,系統老是會嘗試的規則,此條規則將應用放在dev.eng隊列中。

queuePlacementPolicy節點整個能夠省略不配置。若是是這樣的話,就跟指定了下面的配置是同樣的。

<queuePlacementPolicy>
  <rule name="specified" />
  <rule name="user" />
</queuePlacementPolicy>

換句話說,除非隊列顯示地聲明,不然將尋找與用戶的名字相同的隊列,若是有必要,會建立與用戶的名稱同樣的隊列。

另外一個簡單的隊列指定規則是全部應用指定放於相同(默認)隊列中。這樣,每一個應用都會分到相等的資源,而不是按照用戶。對應的規則以下:

<queuePlacementPolicy>
   <rule name="default" />
</queuePlacementPolicy>

也能夠不使用配置文件來設置規則,那就是將屬性yarn.scheduler.fair.user-as-default-queue設置爲false,這樣應用就會都進入默認隊列中,而不是按照用戶分的隊列中。另外,yarn.scheduler.fair.allow-undeclared-pools應該設置爲false,這樣用戶就不可以在運行時動態建立隊列了

優先佔有
當一個做業提交到一臺繁忙的集羣中的一個空隊列中時,這個做業不會當即啓動,直到資源從正在運行在這個集羣中的其它做業釋放出來後纔會啓動。爲了使一個做業啓動的時間是可預料的,公平調度器容許優先佔有。

優先佔有意思是調度器能夠釋放那些佔用的資源超過它們應分配資源的隊列正在使用的容器,而後分配給那些不夠它們本應該分配的資源的隊列。注意優先佔有會下降整個集羣的效率,由於容器終止後,容器以前運行的任務須要從新執行。

若是將屬性yarn.scheduler.fair.preemption設置爲true,則會啓用整個集羣的優先佔有。有兩個相關的優先佔有超時設置。一個針對最小資源的,一個針對公平分配資源的,都是以秒爲單位。默認狀況下,不會設置超時,因此你須要至少設置一個,以便讓能夠佔有容器。

若是隊列等到了超時的時間還沒到分到保證的最少資源。那麼調度器也許會佔其它的容器。經過在配置文件設置頂級屬性defaultMinSharePreemptionTimeout,能夠對全部隊列設置超時的時間。若是想單獨對某個隊列設置,能夠在隊列節點中設置minSharePreemptionTimeout。

一樣地,若是一個隊列佔的資源不到它應得資源的50%,這種狀態持續的時間達到了設置的公平分配的超時時間,那麼調度器也會去佔其它容器。經過在配置文件設置頂級屬性defaultFairSharePreemptionTimeout,能夠對全部隊列設置超時的時間。若是想單獨對某個隊列設置,能夠在隊列節點中設置fairSharePreemptionTimeout。隊列現佔用的資源與應得資源的佔比默認是0.5,咱們能夠經過配置屬性defaultFairSharePreemptionThreshold和fairSharePreemptionThreshold(此屬性針對單個隊列)改變。

延遲調度

全部的YARN調度器儘可能在請求的位置上執行應用。在一個繁忙的集羣中,若是應用請求某個節點,此時,正好其它容器正在這個節點上運行。那麼系統就不會嚴格按照請求來了,它會在相同的機架上再找另一個容器。然而,實際上,若是等待一點時間(不超過幾秒)就會增長能分配到請求節點上容器的機率,所以,也增長了集羣的效率。這個特性叫作"延遲調度"。容量調度器和公平調度器都支持這個特性。

YARN集羣中的每個節點管理器都會週期性地向資源管理器發送一個心跳(默認1秒1次)。心跳會帶着節點管理器上正運行容器的信息還有能提供給新容器的資源信息,因此每一次心跳對一個應用來講是一個潛在的調度啓用新容器的機會。

當採起延遲調度時,調度器不會簡單地使用它獲得的第一次調度機會,而是等待一個指定的最大的錯過的調度機會數,若是達到了最大的錯過的調度機會數,則會不嚴格按照請求來分配節點並準備在下一次調度機會來時進行調度。

對於容量調度器而言,延遲調度經過yarn.scheduler.capacity.node-locality-delay屬性進行配置,將此屬性配置成一個正整數,表示調度器錯過的調度機會數,若是達到了調度機會數,請求的那個節點仍然不能啓用新容器,則將不會按照請求來執行而是在相同機架上尋找任意一個節點。

公平調度器也使用調度機會數也決定延遲,然而它是用集羣大小的比例來表示的。例如,將屬性yarn.scheduler.fair.locality.threshold.node設置爲0.5,意思是調度器應該等到集羣中一半的節點都已經提供了調度機會了,請求尚未知足時,將會在相同機架中尋找另一個節點。相應地,還有一個屬性yarn.scheduler.fair.locality.threshold.rack設置機架的閾值,達到閾值後,將選擇另一個機架,而不是請求的節點所在的機架。

高佔比資源公平分配

當只須要調度一種資源時,例如內存,無論是使用容量調度器仍是公平調度器都很容易分配。若是有兩個用戶的應用須要運行,你能夠經過比較兩個應用所須要的內存來進行分配。然而,當有多種類型資源時,事情就會變得更復雜一些。若是一個用戶的應用須要大量的CPU,可是卻須要少許的內存,其它用戶須要少許CPU,卻須要大量內存,那麼這兩個應用該怎麼比較呢?

YARN框架中的調度器解決這個問題所使用的方法是看看每個用戶的高佔比資源是多少,而後使用這些高佔比的資源作爲集羣資源佔用的標準。這種方法被稱爲"高佔比資源公平分配或簡稱DRF"3。下面用一個簡單的例子加以說明。

假設一個集羣一共有100個CPU和10TB的內存。應用A申請2CPU,300GB內存的容器,應用B則申請6CPU,100GB。A請求的資源分別佔集羣總資源的2%,3%,因此內存是A應用的高佔比資源,由於3%比2%大。B請求的資源分別佔集羣總資源的6%,1%,因此CPU是高佔比資源。能夠看出,就高佔比資源而言,B應用請求的資源是A應用的2倍(6%vs3%),因此在公平分配原則下,B應用分到的容器數將是A應用分到的一半。

默認DRF沒有啓用,因此在資源計算中,僅僅只考慮內存,不考慮CPU。容量調度器經過將capacity-scheduler.xml配置文件中的屬性yarn.scheduler.capacity.resource-calculator的值配置爲org.apache.hadoop.yarn.util.resource.DominantResourceCalculator來啓用DRF。

至於公平調度器,則經過在配置文件配置頂級元素QueueSchedulingPolicy的值爲drf啓用DRF。

延伸閱讀

這一章簡單的歸納性瞭解了一下YARN。若是想更詳細地瞭解,能夠看Arun C. Murthy等人寫的《Apache Hadoop YARN》這本書

本文是筆者翻譯自《OReilly.Hadoop.The.Definitive.Guide.4th.Edition》第一部分第4章,後續將繼續翻譯其它章節。雖盡力翻譯,但奈何水平有限,錯誤再所不免,若是有問題,請不吝指出!但願本文對你有所幫助。
本文轉自個人簡書博客


  1. 若是屬性yarn.scheduler.capacity. .user-limit-factor值比默認的1大,則做業容許使用超過隊列容量的資源

  2. 然而,容量調度器能夠進行預置進程保護, 資源管理器能夠要求應用釋放容器以平衡資源容量

  3. DRF是Ghodsi等人在2011年3月份發表的《高佔比資源公平分配:多種資源的公平分配》這篇文章裏提出來的

相關文章
相關標籤/搜索