Hadoop學習雜記(三)

分享在實現一個MapReduce調度器後遇到一些問題的解決過程
將5個WordCount作業通過example中的main函數提交後,沒有使用響應的調度器調度。
問題:通過日誌發現,5個WordCount作業並沒有加入到map隊列當中,隊列爲空,且tasktracker傳回的map
任務個數始終爲0,調查一下原因。
猜測原因1:hadoop默認提交作業到默認隊列,如果要自定義隊列,則需要配置。目前沒有對map和reduce隊列進行配置,因此作業沒有提交到其中。(不是這樣)
解決:根本原因在於由於初始化作業時未獲取到jobTracker的配置,默認爲local,因此使用了localJobRunner類,而非JobTracker類,導致沒有JobTrakcer和調度器等類的日誌輸出。
解決:嘗試更換JobTracker配置的端口號。還是獲取不到。
找到原因:WordCount作業的配置只使用了默認的配置,沒有加載core-site,hdfs-site和mapred-site三個配置文件,導致JobTracker的配置不生效。
解決:將三個配置文件加入到配置對象中,運行正常。
新問題:在從map隊列中remove元素時,作爲鍵的JobSchedulingInfo對象在比較時爲null,經過日誌調試發現,鍵傳入remove函數的參數並不是null,因此嘗試調試隊列中key的內容。
找到原因:並非JobSchedulingInfo對象爲空而是該對象的newPriority字段(自定義的新優先級對象)爲null。在JobSchedulingInfo對象加入隊列時該字段是經過初始化的,那麼就是因爲oldJobSchedulingInfo對象中該字段爲null導致。
解決:在status對象中添加newPriority即可。
新問題:assignTasks方法中有null錯誤,且map隊列的大小一直在增加。
找到原因:因爲在JobSchedulingInfo的compare方法中,比較了jobid和start time的同時也比較了newPriority,比較方法在查找過程中也在用。因此,在刪除過程中由於newPriority的干擾一直找不到對應的對象。
首先仔細研究TreeMap的 getEntryUsingComparator(Object key)方法:http://www.cnblogs.com/hzmark/archive/2013/01/02/TreeMap-Base.html
1 final Entry<K,V> getEntryUsingComparator(Object key) {
 2     K k = (K) key;
 3     // 獲取比較器
 4 Comparator<? super K> cpr = comparator;
 5 // 其實在調用此方法的get(Object key)中已經對比較器爲null的情況進行判斷,這裏是防禦性的判斷
 6 if (cpr != null) {
 7     // 獲取根節點
 8         Entry<K,V> p = root;
 9         // 遍歷樹
10         while (p != null) {
11             // 獲取key和當前節點的key的比較結果
12             int cmp = cpr.compare(k, p.key);
13             // 查找的key值較小
14             if (cmp < 0)
15                 // p“移動”到左孩子
16                 p = p.left;
17             // 查找的key值較大
18             else if (cmp > 0)
19                 // p“移動”到右節點
20                 p = p.right;
21             // key值相等
22             else
23                 // 返回找到的節點
24                 return p;
25         }
26 }
27 // 沒找到key值對應的節點,返回null
28     return null;
29 }
有代碼可見,remove在調用 getEntryUsingComparator(Object key)時使用了比較器的compare方法,由於map的實現是一個樹結構,因此需要頻繁的比較操作,因此compare的定義會影響remove的執行。
奇哉怪也!!!
remove方法竟然不調用compare方法!
調用了其實,只是日誌沒打印。
找到原因:在將job加入map隊列時使用了newPriority的構造器,其中使用作業執行信息重新計算優先級,而開始時這個值被記爲0,這與在JobInProgress對象中保存的初始值(MAX_VALUE)不同,導致優先級比較失敗,在map中找不到scheduling info。
解決:嘗試在構造器中判斷如果是第一次執行,則置爲MAX_VALUE。
針對map和reduce隊列設置不同的優先級字段,比較時使用各自的優先級。初始化時作業類型爲0。在刪除作業後,將刪除的作業對象的優先級更新,以反映到jobTracker的job列表中,保證下一次task在獲取對應job時信息的正確性,否則會導致下一次查找失敗。目前雙隊列機制工作正常。
下一步的工作是保證優先級算法的正確性(尤其是reduce隊列)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章