使用isolationRunner來分析hadoop集羣中的task失敗

對於使用hadoop進行日誌分析等工作的開發者來說,相信一直都面臨着一個非常頭 疼的問題。那就是:對hadoop的mapreduce作業,在分佈式集羣上進行單個task的單步debug跟蹤調試無法辦到。只能在本地進行調試,然 後提交到集羣中運行,但是集羣中如果某個task總是失敗,要對這一個task進行單步跟蹤就非常困難。其實原因很簡單,因爲當把作業提交到hadoop 集羣進行運行的時候,你事先根本就不知道那個map或者reduce的task會被分配到哪個tasktracker上執行。所以過去的兩年裏,寫 mapreduce應用的工程師們一直面臨着這個懸而未決的問題。只能通過在程序中加日誌,並在作業完成或者失敗後追蹤日誌來進行問題定位。無法達到對程 序象調試單機程序一樣的進行調試。

其 實在hadoop中,有一個好東西,利用這個好東西,就可以實現在集羣中對某個task進行單步調試的需求。這個東西就是 IsolationRunner。IsolationRunner是一個小工具,能夠在tasktracker機器上,重新單獨運行失敗的task,這樣 對於某些大作業(比如job的輸入有100TB),如果因爲某一個task重複失敗而導致整個job失敗,就不用連續不斷的提交job,進行復現,然後定 位某個task失敗的原因,這樣做的代價就會非常的大。如果能夠對失敗的task進行單獨執行,那麼要定位問題的原因代價就變得很小,對工程師來說也非常 的方便。

要 想對失敗的task進行單獨重跑,肯定是有前提的,大家知道,對於map而言,其輸入數據是來自分佈式文件系統(通常是HDFS)中輸入數據的某個 split,所以如果想要重跑map task,其輸入數據就需要被保留下來。同樣對於reduce而言,其輸入是從所有map的中間結果shuffle到該reduce的數據,如果想要重跑 reduce task,這些數據也就需要保留下來。所以爲了提供對失敗的task進行單獨重跑的功能,作業執行過程中的中間結果,或者每個map的輸入數據對應的 split數據,就需要被保留下來。爲此hadoop提供了一個作業的配置選項:keep.failed.task.files,該選項默認爲 false,表示對於失敗的task,其運行的臨時數據和目錄是不會被保存的,這也是hadoop在支持這項功能前默認的做法,因爲如果失敗的task的 臨時文件和目錄被保留的過多,會佔據tasktracker上過多的磁盤空間和文件數,造成磁盤浪費。而當將 keep.failed.task.files選項設置爲true(注意:該配置選項是一個per job的配置),那麼hadoop在執行該job時,當發生map fail或者reduce fail時,就會將task能夠單獨重跑的所有環境都保留下來,比如task運行時對應的job.xml,map input對應的split.dta文件,或者reduce的輸入file.out文件。這樣,要重跑一個map或者reduce task的環境就已經具備。


如何重跑: 
    當fail的task環境具備以後,就可以對單獨的task進行重跑了。重跑的方式爲:

  1. 上到task出錯的tasktracker機器 上
  2. 在該tasktracker上找到fail的task運行時的目錄環境
    1. 在 tasktracker中,對於每一個task都會有一個單獨的執行環境,其中包括其work目錄,其對應的中間文件,以及其運行時需要用到的配置文件等
    2. 這些 目錄是由tasktracker的配置決定,配置選項爲: mapred.local.dir. 該選項可能是一個逗號分隔的路徑list,每個 list都是tasktracker對在其上執行的task建立工作目錄的根目錄。比如如果mapred.local.dir=/disk1 /mapred/local,/disk2/mapred/local,那麼task的執行環境就是mapred.local.dir /taskTracker/jobcache/job-ID/task-attempt-ID
  3. 找到該task的執行工作目錄後,就可以進入到 該目錄下,然後其中就會有該task的運行環境,通常包括一個work目錄,一個job.xml文件,以及一個task要進行操作的數據文件(對map來 說是split.dta,對reduce來說是file.out)。
  4. 找到環境以後,就可以重跑task了。
    1. cd work
    2. hadoop org.apache.hadoop.mapred.IsolationRunner ../job.xml
  •  
    • 這樣,IsolationRunner就會讀取job.xml的配置(這裏的job.xml相當 於提交客戶端的hadoop-site.xml配置文件與命令行-D配置的接合),然後對該map或者reduce進行重新運行。
  1. 到這裏爲止,已經實現了task單獨重跑,但是還是沒有解決對其進行單步斷點debug。這裏利用到的其實是jvm的遠程 debug的功能。方式如下:
    1. 在重跑task之前,export一個環境變 量:export HADOOP_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8888"
    2. 這 樣,hadoop的指令就會通過8888端口將debug信息發送出去
    3. 然後在自己本地的開發環境IDE中(比如 eclipse),launch一個遠程調試,並在代碼中打一個斷點,就可以對在tasktracker上運行的獨立map或者reduce task進行遠程單步調試了。


以下是圖解示意,這裏採用最簡單的wordcount來進行示例。在wordcount的輸入文 件中,加入一行數據,如“guaishushu”,然後修改wordcount的Mapper實現,如下:

 
這樣修改以後,由於數據中有 “guaishushu”的字符串,並且該行一定會被落到某個map的輸入中去,然後代碼中當讀到”guaishushu”的時候會拋出 IOException異常,所以該job在運行過程中就肯定會有一個task失敗。然後,在提交作業時,將 keep.failed.task.files設置爲true,並按如下程序提交,job就開始運行:

  1. 在jobtracker監控web頁面上找到 task失敗的機器,並確保keep.failed.task.files爲true

  2. 上到該tasktracker,並找到該 task運行環境
  3. 進到該task運行環境的work目錄(如果沒有,可以自己創建
  4. export jvm遠程調試環境變量
  5. 運行IsolationRunner
  6. 在自己的開發機IDE環境中launch一個遠 程調試進程
  7. 單步跟蹤示意

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章