1. 編寫目的
本文描述了hadoop中的計算能力調度器(Capacity Scheduler)的實現演算法,計算能力調度器是由Yahoo貢獻的,主要是解決HADOOP-3421中提出的,在調度器上完成HOD(Hadoop On Demand)功能,克服已有HOD的效能低效的缺點。它適合於多使用者共用叢集的環境的調度器。本文解析的計算能力調度器屬於Hadoop 0.20.2。本文組織圖如 下:1)編寫目的 2)計算能力調度器介紹 3)計算能力調度器演算法分析 4)計算能力調度器原始碼分析 5)計算能力調度器與公平調度器比較 6)參考資料。
2. 計算能力調度器介紹
Capacity Scheduler支援以下特性:
(1) 計算能力保證。支援多個隊列,某個作業可被提交到某一個隊列中。每個隊列會配置一定比例的計算資源,且所有提交到隊列中的作業共用該隊列中的資源。
(2) 靈活性。空閑資源會被分配給那些未達到資源使用上限的隊列,當某個未達到資源的隊列需要資源時,一旦出現空閑資源資源,便會分配給他們。
(3) 支援優先順序。隊列支援作業優先順序調度(預設是FIFO)
(4) 多重租賃。綜合考慮多種約束防止單個作業、使用者或者隊列獨佔隊列或者叢集中的資源。
(5) 基於資源的調度。 支援資源密集型作業,允許作業使用的資源量高於預設值,進而可容納不同資源需求的作業。不過,當前僅支援記憶體資源的調度。
3. 計算能力調度器演算法分析
3.1 涉及到的變數
在capacity中,存在三種粒度的對象,分別為:queue、job和task,它們均需要維護的一些資訊:
(1) queue維護的資訊
@ queueName:queue的名稱
@ ulMin:每個使用者的可用的最少資源量(所有使用者均相同),需使用者在設定檔中指定
@ capacityPercent:計算資源比例,需使用者在設定檔中指定
@ numJobsByUser:每個使用者的作業量,用以跟蹤每個使用者提交的作業量,並進行數量的上限限制。
該隊列中map 或reduce task的屬性:
@ capacity:實際的計算資源量,這個隨著tasktracker中slot數目變化(使用者可能在添加或減少機器節點)而動態變化,大小為:capacityPercent*mapClusterCapacity/100
@ numRunningTasks:正在running的task數目
@ numSlotsOccupied:正在running的task佔用的slot總數,注意,在Capacity Scheduler中,running task與slot不一定是一一對應的,每個task可擷取多個slot,這主要是因為該調度支援記憶體資源調度,某個task可能需要多個slot包含的記憶體量。
@ numSlotsOccupiedByUser:每個使用者的作業佔用slot總數,用以限制使用者使用的資源量。
(2) job維護的資訊
priority:作業優先順序,分為五個等級,從大到小依次為:VERY_HIGH,HIGH,NORMAL,LOW,VERY_LOW;
numMapTasks/ numReduceTasks :job的map/reduce task總數
runningMapTasks/ runningMapTasks:job正在啟動並執行map/reduce task數
finishedMapTasks/finishedReduceTasks:job已完成的map/reduce task數
……
(3) task維護的資訊
task開始已耗用時間,目前狀態等
3.2 計算能力調度演算法
當某個tasktracker上出現空閑slot時,調度器依次選擇一個queue、(選中的queue中的)job、(選中的job中的)task,並將該slot分配給該task。下面介紹選擇queue、job和task所採用的策略:
(1) 選擇queue:將所有queue按照資源使用率(numSlotsOccupied/capacity)由小到大排序,依次進行處理,直到找到一個合適的job。
(2) 選擇job:在當前queue中,所有作業按照作業提交時間和作業優先順序進行排序(假設開啟支援優先順序調度功能,預設不支援,需要在設定檔中開啟),調度依次考慮每個作業,選擇符合兩個條件的job:[1] 作業所在的使用者未達到資源使用上限 [2] 該TaskTracker所在的節點剩餘的記憶體足夠該job的task使用。
(3) 選擇task,同大部分調度器一樣,考慮task的locality和資源使用方式。(即:調用JobInProgress中的obtainNewMapTask()/obtainNewReduceTask()方法)
綜合上述,公平調度器的虛擬碼為:
// CapacityTaskScheduler:trackTracker出現空閑slot,為slot尋找合適的task List<Task> assignTasks(TaskTrackerStatus taskTracker) { sortQueuesByResourcesUsesage(queues); for queue:queues { sortJobsByTimeAndPriority(queue); for job:queue.getJobs() { if(matchesMemoryRequirements(job,taskTracker)) { task = job. obtainNewTask(); if(task != null) return task } } } }
4. 計算能力調度器原始碼分析
計算能力調度器位於程式碼封裝的hadoop-0.20.2\src\contrib\capacity-scheduler目錄下。
4.1 原始碼包組成(共5個java檔案)
CapacitySchedulerConf.java:管理設定檔
CapacityTaskScheduler.java:調度器的核心代碼
JobQueuesManager.java:管理作業隊列
MemoryMatcher.java:用於判斷job與記憶體容量是否匹配
JobInitializationPoller.java:作業初始化類,使用者可同時啟動多個線程,加快作業初始化速度。
4.2 CapacityTaskScheduler分析
只介紹調度器最核心的代碼,即CapacityTaskScheduler.java檔案中的代碼。
(1) 幾個基本的內類:
[1] TaskSchedulingInfo(TSI):用以維護某種task(MAP或者REDUCE)的調度資訊,包括numRunningTasks,numSlotsOccupied等
[2] QueueSchedulingInfo(QSI):用以跟蹤某個queue中的調度資訊,包括capacityPercent,ulMin等
[3] TaskSchedulingMgr:調度的核心實現演算法,這是一個抽象類別,有兩個衍生類別,分別為:MapSchedulingMgr和ReduceSchedulingMgr,用以實現map task和reduce task的調度策略
(2) 核心方法(按照執行順序分析):
[1] CapacityTaskScheduler.start(): 調度器初始化,包括載入設定檔,初始化各種對象和變數等。
[2] CapacityTaskScheduler. assignTasks ():當有一個TaskTracker的HeartBeat到達JobTracker時,如果有閒置slot,JobTracker會調用Capacity Scheduler中的assignTasks方法,該方法會為該TaskTracker需找若干個合適的task。在assignTasks方法中,會調用TaskSchedulingMgr中的方法。
前面提到TaskSchedulingMgr是一個抽象類別,它實現了所有衍生類別必須使用的方法:
[3] TaskSchedulingMgr.assignTasks (taskTracker):對外提供的最直接的調用函數,主要作用是為taskTracker選擇一個合適的task,該函數會依次掃描系統中所有的queue(queue已經被排好序,排序類為TaskSchedulingMgr.QueueComparator),對於每個queue,調用getTaskFromQueue(taskTracker, qsi)。
[4] TaskSchedulingMgr.getTaskFromQueue(taskTracker, qsi):從隊列qsi中選擇一個合格作業,這裡的“條件”包括使用者的資源量上限,taskTracker空閑記憶體等。
5. 計算能力調度器與公平調度器對比
(1) 相同點
@ 均支援多使用者多隊列,即:適用於多使用者共用叢集的應用環境
@ 單個隊列均支援優先順序和FIFO調度方式
@ 均支援資源共用,即某個queue中的資源有剩餘時,可共用給其他缺資源的queue
(2) 不同點
@ 核心調度策略不同。 計算能力調度器的調度策略是,先選擇資源使用率低的queue,然後在queue中同時考慮FIFO和memory constraint因素;而公平調度器僅考慮公平,而公平是通過作業缺額體現的,調度器每次選擇缺額最大的job(queue的資源量,job優先順序等僅用於計算作業缺額)。
@ 記憶體約束。計算能力調度器調度job時會考慮作業的記憶體限制,為了滿足某些特殊job的特殊記憶體需求,可能會為該job分配多個slot;而公平調度器對這種特殊的job無能為力,只能殺掉這種task。
6. 參考資料
(1) http://hadoop.apache.org/common/docs/r0.20.2/capacity_scheduler.html
(2) Hadoop 0.20.2 原始碼
轉自 http://dongxicheng.org/mapreduce/hadoop-capacity-scheduler/