hadoop设计的初衷就是容错计算任务(MapReduce task)能够在节点宕机或其它随机错误下自行恢复 但是hadoop并不完美在实际运营中我发现MapReduce Job仍然经常会因为一些偶发性错误而 运行失败所以我决定深入探究一下各种不同因素是如何导致job失败的 如果一个hadoop job的某个给定task在失败预定次(默认是)后整个job就会失败 这可以通过mapredmapmaxattempts和mapredreducemaxattempts属性来设置 一个task可能由于各种偶发原因而失败 比如我发现的情况就有磁盘满hadoop本身的bug或者硬件失效(eg: 磁盘只读) 下面是针对job失败的概率总结的一个大致公式: P[个别task失败的最大次数] = P[task失败] ^ (task总失败次数) P[task成功] = P[个别task失败的最大次数] P[job成功] = P[task成功] ^ (task数量) P[job失败] = P[job成功] P[job失败] = ( P[task失败] ^ (task总失败次数) ) ^ (task数量) task失败的最大次数通过mapredmaxmaxtrackerfailures设置(默认为) 我们来分析一个负载为个map task的job: task数量 最大失败数 P[task失败] P[job失败] 如果task失败概率低于%的话job失败概率几乎可以不计 重点就是保证集群稳定保持较小失败概率 我们同样可以看到mapredmaxtrackerfailures参数的重要性 如果其取值小于时job失败的概率明显上升就算task失败概率降低到% 相较mapper而言 reducer运行的时间更长这意味着其更容易遭受意外事故也就是说我们可以肯定reducer的失败概率比mapper要大很多但是从另一方面来说通常reducer task的数量要小于mapper数量这个又作了一定补偿 下面我们来看看一组基于reducer的失效概率分析: task数量 最大失败数 P[task失败] P[job失败]
从上述数据中可以发现 只有当reducer失败的概率超过%时才会导致一定的job失败几率(同样可发现 task最大失败数低于时job失败率显着上升) 坏节点(有故障的机器节点) 在整个失效模型中还有一个很重要的因子需要考虑那就是失效节点通常若出现整个节点失效那么在此节点上运行的所有task都会失败失效原因可能是因为磁盘损坏(通常的症状是出现 磁盘只读 或 盘符丢失 ) 磁盘写满等一旦出现坏节点你会发现在此节点被列入黑名单之前(被job列入黑名单的节点不会被job再次分配其任务)会有一大堆 map/reduce task失败为了简化我们的分析我假设给定坏节点会导致固定数量的task失败另外我假设给定task只会在给定坏节点上中招一次 因为节点会在不久后被列入黑名单我们用btasks来标记在坏节点上失败过的task 其它task标记为ntasksbtask会在坏节点上遭受一次失败 所以后续如果job再出现最大task失败数 次失败task就会导致job失败在我们的集群中我曾发现一个坏节点引发个task失败 那么我就以此为据 给出reduce阶段失效概率的公式: btasks数量 = 坏节点数量 * P[所有btask都成功] = ( P[task失败概率] ^ (最大task失败数 )) ^ (btasks数量) P[所有ntask都成功] = ( P[task失败] ^ (最大task失败数)) ^ (task数量 btask数量) P[job成功] = P[所有btask成功] * P[所有ntask成功] P[job成功] = (P[task失败]^(最大task失败数 ))^(btask数量) * (P[task失败]^(最大task失败数))^(最大task数 btask数) P[job失败] = P[job成功] 因为mapper数量通常较多所以少数坏节点对于以上公式计算的结果并没有太大的出入但对reducer而言其数量较少所以以上公式计算出 的结果就有比较明显的变化: task数量 最大失败数 P[task失败] 坏节点数量 P[job失败]
值得庆幸的是结果并没有发生戏剧性的变化 在个坏节点的情况下只导致失败率提高到了排除坏节点条件下的~倍 最后的结论就是 hadoop在task失效概率保持较低的情况下容错性还是很好的基于前面的一些数据分析我们发现最大task失败数 最好设置为 当task失败率达到%时你需要开始考虑集群的稳定性了当然你可以通过增大最大task失败数来提高稳定性但是如果有太多task失败 那么job执行的性能也会降低所以再强调一次 重点还是 保持集群稳定 |