【Hadoop】(五)MapReduce 如何解决数据倾斜问题_mapreduce 数据倾斜

一、什么是数据倾斜以及数据倾斜是怎么产生的?

简单来说数据倾斜就是数据的key 的分化严重不均,造成一部分数据很多,一部分数据很少的局面。

举个 word count 的入门例子,它的map 阶段就是形成 (“aaa”,1)的形式,然后在reduce 阶段进行 value 相加,得出 “aaa” 出现的次数。若进行 word count 的文本有100G,其中 80G 全部是 “aaa” 剩下 20G 是其余单词,那就会形成 80G 的数据量交给一个 reduce 进行相加,其余 20G 根据 key 不同分散到不同 reduce 进行相加的情况。如此就造成了数据倾斜,临床反应就是 reduce 跑到 99%然后一直在原地等着 那80G 的reduce 跑完。

简化了的 shuffle 图就是这样。
在这里插入图片描述
这样就能清楚看到,数据经过 map后,由于不同key 的数据量分布不均,在shuffle 阶段中通过 partition 将相同的 key 的数据打上发往同一个 reducer 的标记,然后开始 spill (溢写)写入磁盘,最后merge成最终map阶段输出文件。

如此一来 80G 的 aaa 将发往同一个 reducer ,由此就可以知道 reduce 最后 1% 的工作在等什么了。

二、为什么说数据倾斜与业务逻辑和数据量有关?

从另外角度看数据倾斜,其本质还是在单台节点在执行那一部分数据reduce任务的时候,由于数据量大,跑不动,造成任务卡住。若是这台节点机器内存够大,CPU、网络等资源充足,跑 80G 左右的数据量和跑10M 数据量所耗时间不是很大差距,那么也就不存在问题,倾斜就倾斜吧,反正机器跑的动。所以机器配置和数据量存在一个合理的比例,一旦数据量远超机器的极限,那么不管每个key的数据如何分布,总会有一个key的数据量超出机器的能力,造成 reduce 缓慢甚至卡顿。

业务逻辑造成的数据倾斜会多很多,日常使用过程中,容易造成数据倾斜的原因可以归纳为几点,有前辈早就整理好,我就搬砖了:

  • 分组 注:group by 优于distinct group
    情形:group by 维度过小,某值的数量过多
    后果:处理某值的reduce非常耗时
  • 去重 distinct count(distinct xx)
    情形:某特殊值过多
    后果:处理此特殊值的reduce耗时
  • 连接 join
    情形1:其中一个表较小,但是key集中
    后果1:分发到某一个或几个Reduce上的数据远高于平均值
    情形2:大表与大表,但是分桶的判断字段0值或空值过多
    后果2:这些空值都由一个reduce处理,非常慢

三、如何处理数据倾斜问题呢?

1、调优参数

set hive.map.aggr=true;

set hive.groupby.skewindata=true;

好多小伙伴使用这两个参数的次数真的很多,但是他们不了解这两个参数是怎么解决数据倾斜的,从哪个角度着手的。

hive.map.aggr=true:在map中会做部分聚集操作,效率更高但需要更多的内存。

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

续会持续更新**

需要这份系统化资料的朋友,可以戳这里获取

  • 20
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你回答这个问题。 首先,你需要准备一些数据,例如汽车销售数据,格式可以是CSV或者其他格式。然后,你需要使用Java编写基于HadoopMapReduce程序,实现对这些数据的统计分析。 下面是一个简单的MapReduce程序的示例,用于统计汽车销售数据中不同品牌的销售数量: ```java import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class CarSalesStats { public static class CarSalesMapper extends Mapper<LongWritable, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text brand = new Text(); public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String[] fields = value.toString().split(","); brand.set(fields[0]); context.write(brand, one); } } public static class CarSalesReducer extends Reducer<Text, IntWritable, Text, IntWritable> { public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable value : values) { sum += value.get(); } context.write(key, new IntWritable(sum)); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "Car Sales Stats"); job.setJarByClass(CarSalesStats.class); job.setMapperClass(CarSalesMapper.class); job.setReducerClass(CarSalesReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } } ``` 在这个示例程序中,我们定义了一个`CarSalesMapper`类,用于将输入的CSV文件中每一行的第一个字段(汽车品牌)作为键,将值设为1,表示销售数量为1。然后,我们定义了一个`CarSalesReducer`类,用于对每个品牌的销售数量进行累加求和。最后,在`main`函数中,我们配置了Hadoop作业的输入输出路径,并启动了该作业。 你可以根据自己的需求修改这个示例程序,例如,如果你需要统计不同地区的销售数量,可以将`CarSalesMapper`类中的`brand`变量改为地区的名称,并修改相应的输出格式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值