hadoop MapReduce Job失效模型

hadoop設計的初衷就是容錯.計算任務(MapReduce task)能夠在節點宕機或其它隨機錯誤下自行恢復.

    但是hadoop並不完美,在實際運營中,我發現MapReduce Job仍然經常會因爲一些偶發性錯誤而

    運行失敗.所以我決定深入探究一下各種不同因素是如何導致job失敗的.

    如果一個hadoop job的某個給定task在失敗預定次(默認是4)後,整個job就會失敗.

    這可以通過"mapred.map.max.attempts"和"mapred.reduce.max.attempts"屬性來設置.

    一個task可能由於各種偶發原因而失敗 - 比如我發現的情況就有磁盤滿,hadoop本身的bug,或者硬件失效(e.g.: 磁盤只讀).

    下面是針對job失敗的概率總結的一個大致公式:

    P[個別task失敗的最大次數] = P[task失敗] ^ (task總失敗次數)

    P[task成功] = 1 - P[個別task失敗的最大次數]

    P[job成功] = P[task成功] ^ (task數量)

    P[job失敗] = 1 - P[job成功]

    P[job失敗] = 1 - (1 - P[task失敗] ^ (task總失敗次數) ) ^ (task數量)

    task失敗的最大次數通過mapred.max.max.tracker.failures設置(默認爲4).

    我們來分析一個負載爲100000個map task的job:

    task數量  最大失敗數  P[task失敗]  P[job失敗]

    100000  4  0.01  0.00099950017664

    100000  4  0.02  0.015872681207036

    100000  4  0.03  0.077806338804489

    100000  4  0.04  0.22585828487781

    100000  4  0.05  0.46473961691604

    100000  4  0.06  0.72637819455556

    100000  4  0.01  0.00099950017664

    100000  3  0.01  0.095162627208542

    100000  3  0.005  0.012422200279389

    100000  2  0.005  0.91791756653541

    如果task失敗概率低於1%的話,job失敗概率幾乎可以不計. 重點就是保證集羣穩定,保持較小失敗概率   .

    我們同樣可以看到"mapred.max.tracker.failures"參數的重要性, 如果其取值小於4時,job失敗的概率明顯上升,就算task失敗概率降低到0.5%   .

    相較mapper而言, reducer運行的時間更長,這意味着其更容易遭受意外事故.也就是說,我們可以肯定reducer的失敗概率比mapper要大很多.但是從另一方面來說,通常reducer task的數量要小於mapper數量,這個又作了一定補償.

    下面我們來看看一組基於reducer的失效概率分析:

    task數量  最大失敗數  P[task失敗]  P[job失敗]

    300  1

    0.1  0.99999999999998

    300  2

    0.1  0.95095910592871

    300  3

    0.1  0.2592929678439

    300  4

    0.1  0.029555922215749

    300 ; 4  0.01  0.00000299999553

    300  4

    0.05

    0.001873249134037

    300  4  0.1  0.029555922215749

    300  4

    0.2  0.38145442906123

    300  4

    0.3  0.9128299934708

    從上述數據中可以發現, 只有當reducer失敗的概率超過10%時纔會導致一定的job失敗機率.(同樣可發現, task最大失敗數低於3時,job失敗率顯著上升).
   壞節點(有故障的機器節點)

    在整個失效模型中還有一個很重要的因子需要考慮,那就是失效節點.通常若出現整個節點失效,那麼在此節點上運行的所有task都會失敗,失效原因可能是因爲磁盤損壞(通常的症狀是出現 磁盤只讀   或 盤符丟失   ), 磁盤寫滿等.一旦出現壞節點,你會發現在此節點被列入黑名單之前(被job列入黑名單的節點不會被job再次分配其任務),會有一大堆 map/reduce task失敗.爲了簡化我們的分析,我假設給定壞節點會導致固定數量的task失敗.另外,我假設給定task只會在給定壞節點上中招一次, 因爲節點會在不久後被列入黑名單.我們用"b-tasks"來標記在壞節點上失敗過的task, 其它task標記爲"n-tasks"."b-task"會在壞節點上遭受一次失敗, 所以後續如果job再出現"最大task失敗數 - 1"次失敗task就會導致job失敗.在我們的集羣中,我曾發現一個壞節點引發3個task失敗, 那麼我就以此爲據, 給出reduce階段失效概率的公式:

    b-tasks數量 = 壞節點數量 * 3

    P[所有b-task都成功] = (1 - P[task失敗概率] ^ (最大task失敗數 - 1)) ^ (b-tasks數量)

    P[所有n-task都成功] = (1 - P[task失敗] ^ (最大task失敗數)) ^ (task數量 - b-task數量)

    P[job成功] = P[所有b-task成功] * P[所有n-task成功]

    P[job成功] = (1-P[task失敗]^(最大task失敗數 - 1))^(b-task數量) * (1-P[task失敗]^(最大task失敗數))^(最大task數 - b-task數)

    P[job失敗] = 1 - P[job成功]

    因爲mapper數量通常較多,所以少數壞節點對於以上公式計算的結果並沒有太大的出入.但對reducer而言,其數量較少,所以以上公式計算出

    的結果就有比較明顯的變化:

    task數量  最大失敗數  P[task失敗]  壞節點數量  P[job失敗]

    300  4  0.1  0

    0.02955592221574

    300  4  0.1  1

    0.03217402532872

    300  4  0.1  2

    0.03478506521768

    300  4  0.1  5

    0.04257599583811

    300  4  0.05  0  0.00187324913403

    300  4  0.05

    5

    0.00364969637240

    300  4  0.05  10

    0.00542298192335

    300  4  0.05  20

    0.00896009046141

    值得慶幸的是結果並沒有發生戲劇性的變化 - 在5個壞節點的情況下,只導致失敗率提高到了排除壞節點條件下的1.5~2倍.

    最後的結論就是, hadoop在task失效概率保持較低的情況下,容錯性還是很好的.基於前面的一些數據分析,我們發現"最大task失敗數 " 最好設置爲4, 當task失敗率達到1%時,你需要開始考慮集羣的穩定性了.當然,你可以通過增大"最大task失敗數"來提高穩定性,但是如果有太多task失敗, 那麼job執行的性能也會降低.所以再強調一次, 重點還是 ---  保持集羣穩定 .

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