mapreduce job任务非常慢

1、application日志

2016-08-11 14:48:15,174 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Ramping down all scheduled reduces:0
2016-08-11 14:48:15,174 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Going to preempt 0
2016-08-11 14:48:15,174 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Recalculating schedule, headroom=0
2016-08-11 14:48:15,174 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Reduce slow start threshold not met. completedMapsForReduceSlowstart 1
<span style="color:#ff6666;">2016-08-11 14:48:16,176 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Ramping down all scheduled reduces:0
</span>2016-08-11 14:48:16,177 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Going to preempt 0
2016-08-11 14:48:16,177 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Recalculating schedule, headroom=0
2016-08-11 14:48:16,177 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Reduce slow start threshold not met. completedMapsForReduceSlowstart 1
2016-08-11 14:48:17,179 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Ramping down all scheduled reduces:0
2016-08-11 14:48:17,179 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Going to preempt 0
2016-08-11 14:48:17,179 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Recalculating schedule, headroom=0
2016-08-11 14:48:17,179 INFO [RMCommunicator Allocator] org.apache.hadoop.mapreduce.v2.app.rm.RMContainerAllocator: Reduce slow start threshold not met. completedMapsForReduceSlowstart 1


程序中大量的上面日志出现,跟踪RMContainerAllocator代码:


 // availableMemForMap must be sufficient to run at least 1 map
      if (ResourceCalculatorUtils.computeAvailableContainers(availableResourceForMap,
        mapResourceRequest, getSchedulerResourceTypes()) <= 0) {
        // to make sure new containers are given to maps and not reduces
        // ramp down all scheduled reduces if any
        // (since reduces are scheduled at higher priority than maps)
        LOG.info("Ramping down all scheduled reduces:"
            + scheduledRequests.reduces.size());
        for (ContainerRequest req : scheduledRequests.reduces.values()) {
          pendingReduces.add(req);
        }
        scheduledRequests.reduces.clear();

computeAvailableContainers:
<pre name="code" class="html">  public static int computeAvailableContainers(Resource available,
                                                  Resource required, EnumSet<SchedulerResourceTypes> resourceTypes) {
    if (resourceTypes.contains(SchedulerResourceTypes.CPU)) {
      return Math.min(available.getMemory() / required.getMemory(),
              available.getVirtualCores() / required.getVirtualCores());
    }
    return available.getMemory() / required.getMemory();
  }


 

 

  // get available resources for this job
    Resource headRoom = getAvailableResources();
    if (headRoom == null) {
      headRoom = Resources.none();
    }
    LOG.info("Recalculating schedule, headroom=" + headRoom);
    //check for slow start
    if (!getIsReduceStarted()) {//not set yet
      int completedMapsForReduceSlowstart = (int)Math.ceil(reduceSlowStart * 
                      totalMaps);
      if(completedMaps < completedMapsForReduceSlowstart) {
        LOG.info("Reduce slow start threshold not met. " +
              "completedMapsForReduceSlowstart " + 
            completedMapsForReduceSlowstart);
        return;
      } else {
        LOG.info("Reduce slow start threshold reached. Scheduling reduces.");
        setIsReduceStarted(true);
      }
    }
    
    //if all maps are assigned, then ramp up all reduces irrespective of the
    //headroom
    if (scheduledMaps == 0 && numPendingReduces > 0) {
      LOG.info("All maps assigned. " +
          "Ramping up all remaining reduces:" + numPendingReduces);
      scheduleAllReduces();
      return;
    }


从上面两段代码说明资源以及不够用了



2、从nm日志看,请求的物理内存是25G,太多了,导致其他job获取不到资源,


2016-08-11 14:48:42,560 INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl: Memory usage of ProcessTree 30460 for container-id container_1470814634002_0543_01_000008: 410.9 MB of 25 GB physical memory used; 1.7 GB of 125 GB virtual memory used
2016-08-11 14:48:45,609 INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl: Memory usage of ProcessTree 30460 for container-id container_1470814634002_0543_01_000008: 410.8 MB of 25 GB physical memory used; 1.7 GB of 125 GB virtual memory used
2016-08-11 14:48:48,659 INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl: Memory usage of ProcessTree 30460 for container-id container_1470814634002_0543_01_000008: 410.8 MB of 25 GB physical memory used; 1.7 GB of 125 GB virtual memory used
2016-08-11 14:48:51,708 INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl: Memory usage of ProcessTree 30460 for container-id container_1470814634002_0543_01_000008: 410.8 MB of 25 GB physical memory used; 1.7 GB of 125 GB virtual memory used
2016-08-11 14:48:54,756 INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl: Memory usage of ProcessTree 30460 for container-id container_1470814634002_0543_01_000008: 410.8 MB of 25 GB physical memory used; 1.7 GB of 125 GB virtual memory used
2016-08-11 14:48:57,804 INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl: Memory usage of ProcessTree 30460 for container-id container_1470814634002_0543_01_000008: 410.8 MB of 25 GB physical memory used; 1.7 GB of 125 GB virtual memory used
2016-08-11 14:49:00,857 INFO org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl: Memory usage of ProcessTree 30460 for container-id container_1470814634002_0543_01_000008: 410.8 MB of 25 GB physical memory used; 1.7 GB of 125 GB virtual memory used
2016-08-11 14:49:03,904 INFO org.apache.hadoo


3、于是修改配置

  <property>
    <name>yarn.scheduler.minimum-allocation-mb</name>
    <value>2048</value>
  </property>


问题解决




<think>嗯,用户现在问的是关于MapReduce中的数据倾斜问题。之前他们问过为什么Shuffle阶段需要排序,现在转向数据倾斜,可能是因为他们遇到了性能问题,或者在学习过程中发现了这个常见挑战。我需要先回顾一下数据倾斜在MapReduce中的定义和常见原因。 首先,数据倾斜指的是在分布式计算中,某些节点处理的数据量远大于其他节点,导致这些节点成为瓶颈,拖整个作业的执行速度。这在MapReduce中尤其常见,尤其是在Reduce阶段,当某个或某些Reducer接收到的Key对应的数据量极大时,就会出现倾斜。 接下来,用户可能想知道数据倾斜的表现形式、原因、以及解决方法。我需要分步骤来组织回答,确保结构清晰。可能的原因包括Key分布不均匀、业务逻辑导致的特定Key集中,或者分区函数不合理。解决方法可能涉及自定义分区、Combiner的使用、增加Reducer数量、或者采用二次排序等技术。 另外,用户之前的问题涉及到Shuffle阶段的排序,可能现在想了解数据倾斜是否与排序有关。需要明确数据倾斜主要与数据分布和分区有关,而排序虽然影响Shuffle的效率,但本身不直接导致倾斜。不过,排序可能加剧倾斜带来的性能问题,因为大量数据需要排序和传输。 我需要考虑用户可能的背景,可能是学生或者刚接触大数据处理的人,需要用简单易懂的语言解释概念,同时提供实际例子帮助理解。例如,处理单词计数时,某些高频词(如“the”)会导致某个Reducer负载过重。 还要注意用户可能想知道如何检测数据倾斜,比如通过日志或监控工具观察各Reducer的处理时间。此外,解决方案需要具体,比如如何自定义分区器,或者使用随机前缀来分散热点Key。 最后,总结部分要强调数据倾斜的危害和解决思路,确保用户理解关键点。可能需要提醒用户根据具体场景选择解决方案,因为不同方法有各自的适用场景和代价。</think>--- ### **MapReduce数据倾斜问题详解** 数据倾斜(Data Skew)是MapReduce中**因数据分布不均导致的性能瓶颈问题**,表现为**部分Reduce任务处理的数据量远超其他任务**,最终拖整体作业速度。以下是系统分析: --- #### **1. 数据倾斜的表现与危害** - **典型现象**: - 大部分Reduce任务快速完成,但1~2任务长时间运行(例如处理80%的数据)。 - 作业总进度卡在`99%`(剩余任务处理巨量数据)。 - **核心危害**: - **资源浪费**:部分节点负载过高,其他节点空闲。 - **作业超时**:倾斜任务可能因超时失败,需重试甚至导致作业失败。 - **扩展性丧失**:增加计算资源无法缓解倾斜问题。 --- #### **2. 数据倾斜的常见原因** | **原因类型** | **具体场景示例** | |---------------------|---------------------------------------------------------------------------------| | **Key分布不均** | - 日志分析中某些用户访问量极大(如明星账号)。<br>- 自然语言处理中高频词(如“的”“是”)。 | | **业务逻辑缺陷** | - 分区函数未考虑Key分布(如直接哈希分区导致热点Key集中)。 | | **数据特性影响** | - Join操作中某个表存在大量重复关联键。<br>- 空值(Null)被分配到同一分区。 | | **Shuffle设计限制** | - 默认分区器(HashPartitioner)对非均匀Key分布不敏感。 | --- #### **3. 数据倾斜的解决方案** ##### **(1) 预处理阶段优化** - **采样与Key拆分**: - **随机前缀法**:对热点Key添加随机前缀(如`热点Key_1`, `热点Key_2`),分散到多个Reduce任务。 ```java // 示例:为高频Key添加随机前缀 String skewedKey = "hot_key"; String newKey = skewedKey + "_" + random.nextInt(10); // 拆分为10个子Key ``` - **Combine阶段聚合**:在Map端预聚合(Combiner),减少传输到Reduce端的数据量。 ##### **(2) 分布式计算策略调整** - **自定义分区器(Partitioner)**: 根据Key分布设计分区规则,避免热点Key集中。例如,将高频Key均匀分配到多个分区。 ```java public class SkewAwarePartitioner extends Partitioner<Text, IntWritable> { @Override public int getPartition(Text key, IntWritable value, int numPartitions) { if (key.toString().equals("hot_key")) { return (key.hashCode() & Integer.MAX_VALUE) % numPartitions; // 强制分散 } return defaultPartition(key, numPartitions); // 常规哈希分区 } } ``` - **动态调整Reducer数量**: 根据数据分布动态增加Reducer数量,例如对高频Key分配更多Reducer。 ##### **(3) 计算逻辑重构** - **Map端Join(Map-Side Join)**: 若倾斜由Join操作引起,改用Map端Join(如使用DistributedCache加载小表)。 - **二次排序(Secondary Sort)**: 对Key添加次级排序字段,分散处理压力(例如将热点Key按时间戳分片)。 ##### **(4) 外部工具辅助** - **使用Spark或Flink替代**: 现代计算框架(如Spark的`repartition`、Flink的`rebalance`)内置更灵活的数据倾斜处理机制。 - **借助中间存储**: 将倾斜数据写入HBase或Redis,通过外部系统分散计算压力。 --- #### **4. 实际案例:电商订单分析** - **场景**:统计每个用户的订单总金额,但少数用户(如“VIP用户”)订单量占全量80%。 - **倾斜处理步骤**: 1. **识别热点Key**:采样发现用户ID为`user123`的订单占比极高。 2. **Key拆分**:将`user123`的订单随机拆分为`user123_1`, `user123_2`等子Key。 3. **多阶段聚合**: - 第一阶段:按子Key聚合部分结果。 - 第二阶段:合并所有子Key的聚合结果,得到`user123`的总金额。 --- #### **5. 数据倾斜的检测方法** - **日志分析**: 观察作业计数器(Counter)中的`Reduce input records`,对比各Reducer处理的数据量差异。 - **可视化工具**: 通过Hadoop JobHistory或YARN Timeline Server查看任务时间分布。 - **抽样统计**: 在Map阶段对Key进行采样,提前发现潜在倾斜(如使用`Reservoir Sampling`算法)。 --- ### **总结** **数据倾斜的本质是分布式系统中的负载不均问题**,需结合业务特点从多维度解决: 1. **预防**:优化Key设计(如避免单一高频Key)。 2. **分散**:通过分区策略或Key拆分均衡负载。 3. **加速**:利用Combiner、Map端聚合减少数据传输。 4. **旁路**:引入外部系统或更换计算框架。 实际应用中,通常需要**组合多种方法**(如“采样+自定义分区+Combiner”)才能有效缓解倾斜。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值