MapReduce的数据倾斜及其优化方式

@Author  : Spinach | GHB
@Link    : http://blog.csdn.net/bocai8058

MapReduce的数据倾斜和解决方式

数据倾斜

根据MapReduce的执行流程以发现,在map端是不会产生数据倾斜的,因为它会根据分片规则将数据进行均匀的切分成一个个固定大小的数据片段,而且每一个数据片段都会有一个maptask去处理,因此,数据倾斜只会在reduce端产生,因为map程序会将数据处理成键值对的形式,这样就有可能出现有的键相同的数据多,有的键相同的数据少。因此在进行partition分区的时候会将键相同的数据分配到同一个reduce当中去,这样就会导致有的reduce要处理数据会很多,有的就会很少,从而导致数据倾斜问题的产生。所以我们需要根据实际数据的特点自定义partition分区的规则,这样就能很好的解决数据倾斜的问题。

解决方法

重写Partitioner类的getPartition

public class Screw2Partition extends Partitioner<Text, IntWritable> 
{
     @Override
     public int getPartition(Text text, IntWritable intWritable, int numPartitions) 
     {
         Random r = new Random();
         //返回的是分区的随机的一个ID
         return r.nextInt(numPartitions);
     }
}
  • 自定义partition
  • 随机分区

引用:https://segmentfault.com/a/1190000009166436 | https://blog.csdn.net/WYpersist/article/details/79797075

MapReduce的优化方式

  1. Map和Reduce的数量
  2. 出现数据倾斜,需要自定义partitioner
  3. 自定义combiner,还可以调参min.num.spill.for.combine,默认是3,也就是说spill的文件数在默认情况下由三个的时候就要进行combine操作,最终减少磁盘数据;
  4. MapReduce中Kvbuffer的大小默认100M,可以通过mapreduce.task.io.sort.mb(default:100)参数来调整。可以根据不同的硬件尤其是内存的大小来调整,调大的话,会减少磁盘spill的次数此时如果内存足够的话,一般都会显著提升性能。spill一般会在Buffer空间大小的80%开始进行spill(因为spill的时候还有可能别的线程在往里写数据,因为还预留空间,有可能有正在写到Buffer中的数据),可以通过mapreduce.map.sort.spill.percent(default:0.80)进行调整,Map Task在计算的时候会不断产生很多spill文件,在Map Task结束前会对这些spill文件进行合并,这个过程就是merge的过程。mapreduce.task.io.sort.factor(default:10),代表进行merge的时候最多能同时merge多少spill,如果有100个spill个文件,此时就无法一次完成整个merge的过程,这个时候需要调大mapreduce.task.io.sort.factor(default:10)来减少merge的次数,从而减少磁盘的操作;
  5. 减少磁盘IO和网络IO还可以进行:压缩,对spill,merge文件都可以进行压缩。中间结果非常的大,IO成为瓶颈的时候压缩就非常有用,可以通过mapreduce.map.output.compress(default:false)设置为true进行压缩,数据会被压缩写入磁盘,读数据读的是压缩数据需要解压,在实际经验中Hive在Hadoop的运行的瓶颈一般都是IO而不是CPU,压缩一般可以10倍的减少IO操作,压缩的方式Gzip,Lzo,BZip2,Lzma等,其中Lzo是一种比较平衡选择,mapreduce.map.output.compress.codec(default:org.apache.hadoop.io.compress.DefaultCodec)参数设置。但这个过程会消耗CPU,适合IO瓶颈比较大。
  6. 增大内存大小
  7. copier时可以调节并行度。默认情况下,每个Reducer只会有5个map端并行的下载线程在从map下数据,如果一个时间段内job完成的map有100个或者更多,那么reduce也最多只能同时下载5个map的数据,所以这个参数比较适合map很多并且完成的比较快的job的情况下调大,有利于reduce更快的获取属于自己部分的数据。 在Reducer内存和网络都比较好的情况下,可以调大该参数;

引用:https://blog.csdn.net/aijiudu/article/details/72353510 | https://blog.csdn.net/freefish_yzx/article/details/77499069


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值