Hadoop Job Scheduler作業調度器(轉載)

Hadoop Job Scheduler作業調度器
2010-08-16 14:59
作者:hovlj_1130 | 可以任意轉載, 但轉載時務必以超鏈接形式標明文章原始出處 和 作者信息 及 版權聲明
http://hi.baidu.com/hovlj_1130/blog/item/fb84dd1e3558d8f8e0fe0b8e.html

Hadoop Job Scheduler
Hadoop的作業調度器,可以以插件的方式加載,常見的作業調度器有三種:
默認調度算法FIFO
計算能力調度算法Capacity Scheduler(Yahoo!開發)
公平份額調度算法Fair Scheduler(Facebook開發)

默認調度算法FIFO
簡介:
最早的Hadoop Map/Reduce計算架構中,JobTracker在進行作業調度時使用的是FIFO(First In First Out)算法。所有用戶的作業都被提交到一個隊列中,然後由JobTracker先按照作業的優先級高低,再按照作業提交時間的先後順序選擇將被執行的作業。
優點:
調度算法簡單明瞭,JobTracker工作負擔輕。
缺點:
忽略了不同作業的需求差異。例如如果類似對海量數據進行統計分析的作業長期佔據計算資源,那麼在其後提交的交互型作業有可能遲遲得不到處理,從而影響到用戶的體驗。
新的調度算法:
當前,新的調度器已經作爲插件的形式集成在Hadoop當中。

計算能力調度算法Capacity Scheduler
基礎知識:
Capacity Scheduler的每個隊列中採用的調度策略是FIFO算法。
Capacity Scheduler默認情況下不支持優先級,但是可以在配置文件中開啓此選項,如果支持優先級,調度算法就是帶有優先級的FIFO。
Capacity Scheduler不支持優先級搶佔,一旦一個作業開始執行,在執行完之前它的資源不會被高優先級作業所搶佔。
Capacity Scheduler對隊列中同一用戶提交的作業能夠獲得的資源百分比進行了限制以使同屬於一用戶的作業不能出現獨佔資源的情況。

配置:
#將capacity scheduler的jar包copy到lib目錄下
cp $HADOOP_HOME/contrib/capacity-scheduler/hadoop-*-capacity-scheduler.jar $HADOOP_HOME/lib/

#配置mapred-site.xml
#添加mapred.jobtracker.taskScheduler設置爲org.apache.hadoop.mapred.CapacityTaskScheduler
#這裏分了兩個組,在mapred.queue.names裏面定義,同時組的具體配額在capacity-scheduler.xml裏面定義
vi mapred-site.xml

<property>
<name>mapred.jobtracker.taskScheduler</name>
<value>org.apache.hadoop.mapred.CapacityTaskScheduler</value>
</property>
<property>
<name>mapred.queue.names</name>
<value>default,putindb</value>
</property>

#設置具體的queue的配額信息,前面兩組分別配置default和putindb組,後面是整理的配置
vi capacity-scheduler.xml
<?xml version="1.0"?>
<configuration>
<property>
<name>mapred.capacity-scheduler.queue.default.capacity</name>
<value>5</value>
</property>
<property>
<name>mapred.capacity-scheduler.queue.default.supports-priority</name>
<value>true</value>
</property>
<property>
<name>mapred.capacity-scheduler.queue.default.minimum-user-limit-percent</name>
<value>100</value>
</property>
<property>
<name>mapred.capacity-scheduler.queue.default.maximum-initialized-jobs-per-user</name>
<value>2</value>
</property>

<property>
<name>mapred.capacity-scheduler.queue.putindb.capacity</name>
<value>95</value>
</property>
<property>
<name>mapred.capacity-scheduler.queue.putindb.supports-priority</name>
<value>true</value>
</property>
<property>
<name>mapred.capacity-scheduler.queue.putindb.minimum-user-limit-percent</name>
<value>100</value>
</property>
<property>
<name>mapred.capacity-scheduler.queue.putindb.maximum-initialized-jobs-per-user</name>
<value>2</value>
</property>

<property>
<name>mapred.capacity-scheduler.default-supports-priority</name>
<value>true</value>
</property>
<property>
<name>mapred.capacity-scheduler.default-minimum-user-limit-percent</name>
<value>100</value>
</property>
<property>
<name>mapred.capacity-scheduler.default-maximum-initialized-jobs-per-user</name>
<value>2</value>
</property>

<property>
<name>mapred.capacity-scheduler.init-poll-interval</name>
<value>5000</value>
</property>
<property>
<name>mapred.capacity-scheduler.init-worker-threads</name>
<value>5</value>
</property>

</configuration>

配置完成後,重啓jobtracker即可。
stop-mapred.sh
start-mapred.sh
注意在提交Job時,記得設置job.set(),指定組或者Pool;

如何選擇合適的作業去執行 
爲隊列定義了一個指標—隊列中正在運行的任務數與其應該分得的計算資源(配置文件中爲此隊列分配了相應數量的資源,而實際中該隊列可能沒有分配到)之間的比值。當系統中出現空閒的task tracker,算法會首先選擇一個該比值最低的隊列。 
隊列被選中後,將按照作業優先級(如果支持的話)和提交時間順序選擇執行的作業。 
在選擇作業的時候,還需要考慮作業所屬的用戶是否已經超出了他所能使用的資源限制。 
此外,還會考慮task tracker內存資源是否滿足作業的要求。 

內存資源的有效管理 
Capacity Scheduler能有效地對hadoop集羣的內存資源進行管理,以支持內存密集型應用。 
作業對內存資源需求高時,調度算法將把該作業的相關任務分配到內存資源充足的task tracker上。 
在作業選擇過程中,Capacity Scheduler會檢查空閒task tracker上的內存資源是否滿足作業要求。task tracker上的空閒資源(內存)數量值可以通過task tracker的內存資源總量減去當前已經使用的內存數量得到,而後者包含在task tracker向job tracker發送的週期性心跳信息中。 
目前,基於內存的調度只能在linux平臺下起作用,關於內存調度的相關參數可以通過配置文件來設置。

公平份額調度算法Fair Scheduler
設計思想 
儘可能保證所有的作業都能夠獲得等量的資源份額。系統中只有一個作業執行時,它將獨佔集羣所有資源。有其他作業被提交時就會有TaskTracker被釋放並分配給新提交的作業,以保證所有的作業都能夠獲得大體相同的計算資源。 
作業池 
用戶提交的作業將會放進一個能夠公平共享資源的pool(池)中。 
每個作業池設定了一個最低資源保障(a guaranteed minimum share),當一個池中包含job時,它至少可以獲得minimum share的資源——最低保障資源份額機制。 
池中的作業獲得一定份額的資源。 
可以通過配置文件限制每個池中的作業數量。 
缺省情況下,每個作業池中選擇將要執行的作業的策略是FIFO策略,先按照優先級高低排序,然後再按照提交時間排序。 
作業和作業池的權值weight 
缺省情況下,Fair Scheduler會爲每一個用戶建立一個單獨的pool。所有用戶能夠獲得等量的資源份額而無論他提交了多少作業,而每個pool中,各個作業將平分分配給所在池的資源。 
實際應用中,無論是作業池還是作業,都被賦予一定的權值,並以此爲依據獲得相應比例的資源。這種情況下,作業池和作業在資源分配時不是嚴格的平均分配,但這有利於根據作業的重要程度及實際需求合理分配資源。
如何選擇合適的作業執行 
默認是FIFO策略,此外還有一種基於赤字的策略。 
Fair Scheduler爲每個作業定義了一個deficit(赤字)指標。 
Deficit是一個作業在理想情況下的獲得的計算資源和實際中獲得的計算資源之間的差距。 
Fair Scheduler會每隔幾百毫秒觀察每個作業中有多少任務已經在這個時間間隔內執行,並將結果與它應得的資源份額比較,以更新該作業的deficit值。一旦有空閒的task tracker出現,首先分配給當前具有最高deficit值的作業。 
例外——如果系統中存在着尚未獲得最低資源保障的作業池,那麼該池中的作業將會優先調度,而選擇池中的作業需要根據它們的deficit來決定。這樣做是爲了儘可能滿足作業池最低保障資源份額的機制。
如何確定每個作業的資源份額 
缺省情況是平分資源,此外提供一種基於權值的資源分配方法。 
作業資源份額的計算是根據作業的權值將集羣的資源總量劃分給各個可以運行的作業。 
默認情況下,權值基於作業優先級,每個優先級對應的權值是低一個優先級的2倍(優先級共有VERY_HIGH, HIGH, NORMAL, LOW, VERY_LOW五個等級,則VERY_HIGH具有4倍NORMAL的權值)。 
作業和作業池的權值可以在池配置文件中進行設定,例如可以基於作業的大小和提交時間來設定。 
作業池的最低資源保障也是按照權值比例分配給其中的作業。

配置:
#將fair scheduler的jar包copy到lib目錄下
cp $HADOOP_HOME/contrib/fairscheduler/hadoop-*-fairscheduler.jar $HADOOP_HOME/lib/

#配置mapred-site.xml 
vi mapred-site.xml

<property>
<name>mapred.jobtracker.taskScheduler</name>
<value>org.apache.hadoop.mapred.FairScheduler</value>
</property>

<property>
<name>mapred.fairscheduler.allocation.file</name>
<value>$HADOOP_CONF/pools.xml</value>
</property>

<property>
<name>mapred.fairscheduler.preemption</name>
<value>true</value>
</property>

<property>
<name>mapred.fairscheduler.assignmultiple</name>
<value>true</value>
</property>

<property>
<name>mapred.fairscheduler.poolnameproperty</name>
<value>mapred.queue.name</value>
<description>job.set("mapred.queue.name",pool); // pool is set to either 'high' or 'low' </description>
</property>

<property>
<name>mapred.fairscheduler.preemption.only.log</name>
<value>true</value>
</property>

<property>
<name>mapred.fairscheduler.preemption.interval</name>
<value>15000</value>
</property>

<property>
<name>mapred.queue.names</name>
<value>default,putindb</value>
</property>

vi pools.xml
<?xml version="1.0"?>
<allocations>
<pool name="putindb">
<minMaps>90</minMaps>
<minReduces>20</minReduces>
<maxRunningJobs>20</maxRunningJobs>
<weight>2.0</weight>
<minSharePreemptionTimeout>30</minSharePreemptionTimeout>
</pool>

<pool name="default">
<minMaps>9</minMaps>
<minReduces>2</minReduces>
<maxRunningJobs>20</maxRunningJobs>
<weight>1.0</weight>
<minSharePreemptionTimeout>30</minSharePreemptionTimeout>
</pool>
</allocations>

不管是Capacity Scheduler還是Fair Scheduler,我都沒有配置任務搶佔成功。具體表現在:
當一個優先級更高的任務提交時,jobtracker會將新回收的map/reduce單元用於新的這個優先級更高的任務,但是對於一直running而沒有完成的計算資源,jobtracker無法將這些資源回收。也就是說,當一個hadoop集羣裏面的reduce資源有限時(在我們的應用中,map單元都很快就跑完了,但是存在一些長時間的reduce),而一些長時間運行的低優先級的任務佔用完了所有的reduce單元后,新提交的優先級更高的Job的reduce全被pending,而無法搶佔資源運行,導致無法完成。
在網上查到Fair Scheduler將在hadoop 0.21裏實現任務搶佔preemption,網上有一些補丁,但是打上patch4665: Add preemption to the fair scheduler後依舊無法搶佔。
看來只有自己修改源碼了,這個問題不解決,問題很大啊。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章